pub struct BybitHttpClient { /* private fields */ }Expand description
The HTTP client of the Bybit API V5.
It signs every private request with the key pair of the config, and keeps the offset between the clock of the
exchange and the local clock (sync_time), so the timestamp is always inside the
receive window.
- A read is sent once. The client does not retry: the caller decides.
- A command (create, amend, cancel) is sent once too, and never repeated: a repeat is the one way to place an order twice. A lost answer is an unknown outcome, as for every command.
The client is cheap to clone. The limit of the exchange (per second and per endpoint) is not enforced here: the connector throttles through the shared limiter.
§Examples
use brokapi_bybit_protocol::http::client::BybitHttpClient;
let client = BybitHttpClient::new(cfg)?;
let offset = client.sync_time().await?;
assert!(offset.abs() < 5_000, "the clock of the imitation is the local one");Implementations§
Source§impl BybitHttpClient
impl BybitHttpClient
Sourcepub fn new(config: BybitConfig) -> Result<Self, BybitApiError>
pub fn new(config: BybitConfig) -> Result<Self, BybitApiError>
Creates a client from a configuration. No network call is made.
§Errors
BybitApiError::Http (no status) if the HTTP stack cannot be built.
§Examples
use brokapi_bybit_protocol::config::BybitConfig;
use brokapi_bybit_protocol::http::client::BybitHttpClient;
let client = BybitHttpClient::new(BybitConfig::new("key", "secret"))?;
assert_eq!(client.base_url(), "https://api.bybit.com");Sourcepub fn config(&self) -> &BybitConfig
pub fn config(&self) -> &BybitConfig
The configuration the client was made from.
Sourcepub fn timestamp_ms(&self) -> i64
pub fn timestamp_ms(&self) -> i64
The timestamp to put in a request: the local clock moved by the offset of the exchange clock.
Sourcepub async fn sync_time(&self) -> Result<i64, BybitApiError>
pub async fn sync_time(&self) -> Result<i64, BybitApiError>
Reads the clock of the exchange and keeps its offset from the local clock. Returns the offset in milliseconds (positive: the exchange is ahead).
The offset is taken at the middle of the round trip. A request is signed with the corrected time from then on.
§Errors
Sourcepub async fn get_public<T: DeserializeOwned>(
&self,
path: &str,
query: &[(&str, String)],
) -> Result<T, BybitApiError>
pub async fn get_public<T: DeserializeOwned>( &self, path: &str, query: &[(&str, String)], ) -> Result<T, BybitApiError>
GETs a public path (no key) and returns the result of the reply parsed as T.
§Errors
BybitApiError::Api: the exchange refused the request (retCodeis not zero).BybitApiError::RateLimitExceeded: HTTP 429 orretCode10006.BybitApiError::Http: another status, a transport failure, or a timeout.BybitApiError::Parse: the reply is a success but not the JSON thatTexpects.
§Examples
use brokapi_bybit_protocol::error::BybitApiError;
use brokapi_bybit_protocol::http::client::BybitHttpClient;
let client = BybitHttpClient::new(cfg)?;
let time: serde_json::Value = client.get_public("/v5/market/time", &[]).await?;
assert!(time["timeSecond"].is_string());
// A refusal of the exchange keeps its code.
let err = client
.get_public::<serde_json::Value>("/v5/market/orderbook", &[("category", "linear".into()), ("symbol", "NOPEUSDT".into())])
.await
.unwrap_err();
assert!(matches!(err, BybitApiError::Api { code: 10001, .. }));Sourcepub async fn get_private<T: DeserializeOwned>(
&self,
path: &str,
query: &[(&str, String)],
) -> Result<T, BybitApiError>
pub async fn get_private<T: DeserializeOwned>( &self, path: &str, query: &[(&str, String)], ) -> Result<T, BybitApiError>
GETs a private path: signed with the key. Same errors as BybitHttpClient::get_public, and
BybitApiError::Auth when the key is refused.
§Examples
use brokapi_bybit_protocol::http::client::BybitHttpClient;
let client = BybitHttpClient::new(cfg)?;
let wallet: serde_json::Value = client
.get_private("/v5/account/wallet-balance", &[("accountType", "UNIFIED".into())])
.await?;
assert!(wallet["list"].is_array());Sourcepub async fn post_command<T, B>(
&self,
path: &str,
body: &B,
) -> Result<T, BybitApiError>where
T: DeserializeOwned,
B: Serialize,
pub async fn post_command<T, B>(
&self,
path: &str,
body: &B,
) -> Result<T, BybitApiError>where
T: DeserializeOwned,
B: Serialize,
POSTs a command (create, amend, cancel an order) with a JSON body. Never repeats the request.
The body is signed as the exact text that is sent. A transport error or a timeout is an unknown outcome: the caller must find out with a read.
§Errors
The same as BybitHttpClient::get_private.
Sourcepub async fn read_raw(
&self,
method: Method,
path: &str,
query: &[(&str, String)],
body: Option<&Value>,
signed: bool,
) -> Result<(StatusCode, String), BybitApiError>
pub async fn read_raw( &self, method: Method, path: &str, query: &[(&str, String)], body: Option<&Value>, signed: bool, ) -> Result<(StatusCode, String), BybitApiError>
GETs a private path and returns the status and the body text, without parsing and without mapping errors.
An error status is not an Err here. Only a transport failure is.
§Errors
BybitApiError::Http (no status) on a transport failure.
Source§impl BybitHttpClient
impl BybitHttpClient
Sourcepub async fn get_server_time(&self) -> Result<ServerTime, BybitApiError>
pub async fn get_server_time(&self) -> Result<ServerTime, BybitApiError>
GET /v5/market/time.
Sourcepub async fn get_instrument(
&self,
category: &str,
symbol: &str,
) -> Result<InstrumentInfo, BybitApiError>
pub async fn get_instrument( &self, category: &str, symbol: &str, ) -> Result<InstrumentInfo, BybitApiError>
GET /v5/market/instruments-info for one symbol.
§Errors
BybitApiError::Api with code 10001 for a symbol the exchange does not know.
§Examples
use brokapi_bybit_protocol::http::client::BybitHttpClient;
let client = BybitHttpClient::new(cfg)?;
let info = client.get_instrument("linear", "MOCKUSDT").await?;
assert!(info.price_filter.tick_size.is_sign_positive());Sourcepub async fn get_instruments_page(
&self,
category: &str,
limit: u32,
cursor: Option<&str>,
) -> Result<Page<InstrumentInfo>, BybitApiError>
pub async fn get_instruments_page( &self, category: &str, limit: u32, cursor: Option<&str>, ) -> Result<Page<InstrumentInfo>, BybitApiError>
GET /v5/market/instruments-info, one page of a category.
Sourcepub async fn get_order_book(
&self,
category: &str,
symbol: &str,
limit: Option<u32>,
) -> Result<OrderBookView, BybitApiError>
pub async fn get_order_book( &self, category: &str, symbol: &str, limit: Option<u32>, ) -> Result<OrderBookView, BybitApiError>
GET /v5/market/orderbook, limit levels per side (1 to 1000 for linear; the exchange default is 25).
Sourcepub async fn get_ticker(
&self,
category: &str,
symbol: &str,
) -> Result<Ticker, BybitApiError>
pub async fn get_ticker( &self, category: &str, symbol: &str, ) -> Result<Ticker, BybitApiError>
GET /v5/market/tickers for one symbol.
Sourcepub async fn get_recent_trades(
&self,
category: &str,
symbol: &str,
limit: u32,
) -> Result<Vec<PublicTradeRecord>, BybitApiError>
pub async fn get_recent_trades( &self, category: &str, symbol: &str, limit: u32, ) -> Result<Vec<PublicTradeRecord>, BybitApiError>
GET /v5/market/recent-trade, the newest first. limit is 1 to 1000.
Sourcepub async fn get_klines(
&self,
category: &str,
symbol: &str,
interval: &str,
start_ms: Option<i64>,
end_ms: Option<i64>,
limit: u32,
) -> Result<Vec<Kline>, BybitApiError>
pub async fn get_klines( &self, category: &str, symbol: &str, interval: &str, start_ms: Option<i64>, end_ms: Option<i64>, limit: u32, ) -> Result<Vec<Kline>, BybitApiError>
GET /v5/market/kline: candles from start_ms to end_ms, at most limit (1 to 1000), oldest first.
interval is one of 1 3 5 15 30 60 120 240 360 720 D W M.
Sourcepub async fn create_order(
&self,
body: &CreateOrderRequest,
) -> Result<OrderRef, BybitApiError>
pub async fn create_order( &self, body: &CreateOrderRequest, ) -> Result<OrderRef, BybitApiError>
POST /v5/order/create. A command: sent once.
Sourcepub async fn amend_order(
&self,
body: &AmendOrderRequest,
) -> Result<OrderRef, BybitApiError>
pub async fn amend_order( &self, body: &AmendOrderRequest, ) -> Result<OrderRef, BybitApiError>
POST /v5/order/amend. A command: sent once.
Sourcepub async fn cancel_order(
&self,
body: &CancelOrderRequest,
) -> Result<OrderRef, BybitApiError>
pub async fn cancel_order( &self, body: &CancelOrderRequest, ) -> Result<OrderRef, BybitApiError>
POST /v5/order/cancel. A command: sent once.
Sourcepub async fn cancel_all(
&self,
category: &str,
symbol: Option<&str>,
settle_coin: &str,
) -> Result<CancelAllResult, BybitApiError>
pub async fn cancel_all( &self, category: &str, symbol: Option<&str>, settle_coin: &str, ) -> Result<CancelAllResult, BybitApiError>
POST /v5/order/cancel-all for the symbol, or for the whole settle coin when symbol is None.
Sourcepub async fn get_open_orders(
&self,
category: &str,
symbol: Option<&str>,
settle_coin: Option<&str>,
order_id: Option<&str>,
order_link_id: Option<&str>,
limit: u32,
cursor: Option<&str>,
) -> Result<Page<OrderRecord>, BybitApiError>
pub async fn get_open_orders( &self, category: &str, symbol: Option<&str>, settle_coin: Option<&str>, order_id: Option<&str>, order_link_id: Option<&str>, limit: u32, cursor: Option<&str>, ) -> Result<Page<OrderRecord>, BybitApiError>
GET /v5/order/realtime: one page of the working orders (conditional ones included), or the order with the
given orderLinkId or orderId whatever its status (the exchange keeps the 500 latest closed ones).
Sourcepub async fn get_order_history(
&self,
category: &str,
symbol: Option<&str>,
order_id: Option<&str>,
order_link_id: Option<&str>,
limit: u32,
cursor: Option<&str>,
) -> Result<Page<OrderRecord>, BybitApiError>
pub async fn get_order_history( &self, category: &str, symbol: Option<&str>, order_id: Option<&str>, order_link_id: Option<&str>, limit: u32, cursor: Option<&str>, ) -> Result<Page<OrderRecord>, BybitApiError>
GET /v5/order/history: the orders of the last 7 days (or of the given range), closed ones included.
Sourcepub async fn get_executions(
&self,
category: &str,
symbol: Option<&str>,
start_ms: Option<i64>,
end_ms: Option<i64>,
limit: u32,
cursor: Option<&str>,
) -> Result<Page<ExecutionRecord>, BybitApiError>
pub async fn get_executions( &self, category: &str, symbol: Option<&str>, start_ms: Option<i64>, end_ms: Option<i64>, limit: u32, cursor: Option<&str>, ) -> Result<Page<ExecutionRecord>, BybitApiError>
GET /v5/execution/list: fills in [start_ms, end_ms], at most 7 days apart.
Sourcepub async fn get_positions(
&self,
category: &str,
settle_coin: &str,
limit: u32,
cursor: Option<&str>,
) -> Result<Page<PositionRecord>, BybitApiError>
pub async fn get_positions( &self, category: &str, settle_coin: &str, limit: u32, cursor: Option<&str>, ) -> Result<Page<PositionRecord>, BybitApiError>
GET /v5/position/list for the settle coin (every position of the category with a size above zero).
Sourcepub async fn get_wallet_balance(
&self,
) -> Result<Vec<WalletRecord>, BybitApiError>
pub async fn get_wallet_balance( &self, ) -> Result<Vec<WalletRecord>, BybitApiError>
GET /v5/account/wallet-balance of the unified account.
Sourcepub async fn demo_apply_money(
&self,
coin: &str,
amount: Decimal,
) -> Result<Value, BybitApiError>
pub async fn demo_apply_money( &self, coin: &str, amount: Decimal, ) -> Result<Value, BybitApiError>
POST /v5/account/demo-apply-money: adds virtual money to a demo account (coin, amount). The exchange
allows one such request a minute, and only on the demo contour.
Trait Implementations§
Source§impl Clone for BybitHttpClient
impl Clone for BybitHttpClient
Source§fn clone(&self) -> BybitHttpClient
fn clone(&self) -> BybitHttpClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more