Skip to main content

BybitHttpClient

Struct BybitHttpClient 

Source
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

Source

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");
Source

pub fn base_url(&self) -> &str

The base URL requests go to.

Source

pub fn config(&self) -> &BybitConfig

The configuration the client was made from.

Source

pub fn timestamp_ms(&self) -> i64

The timestamp to put in a request: the local clock moved by the offset of the exchange clock.

Source

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

As BybitHttpClient::get_public.

Source

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
§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, .. }));
Source

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());
Source

pub async fn post_command<T, B>( &self, path: &str, body: &B, ) -> Result<T, BybitApiError>

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.

Source

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

Source

pub async fn get_server_time(&self) -> Result<ServerTime, BybitApiError>

GET /v5/market/time.

Source

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());
Source

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.

Source

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).

Source

pub async fn get_ticker( &self, category: &str, symbol: &str, ) -> Result<Ticker, BybitApiError>

GET /v5/market/tickers for one symbol.

Source

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.

Source

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.

Source

pub async fn create_order( &self, body: &CreateOrderRequest, ) -> Result<OrderRef, BybitApiError>

POST /v5/order/create. A command: sent once.

Source

pub async fn amend_order( &self, body: &AmendOrderRequest, ) -> Result<OrderRef, BybitApiError>

POST /v5/order/amend. A command: sent once.

Source

pub async fn cancel_order( &self, body: &CancelOrderRequest, ) -> Result<OrderRef, BybitApiError>

POST /v5/order/cancel. A command: sent once.

Source

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.

Source

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).

Source

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.

Source

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.

Source

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).

Source

pub async fn get_wallet_balance( &self, ) -> Result<Vec<WalletRecord>, BybitApiError>

GET /v5/account/wallet-balance of the unified account.

Source

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

Source§

fn clone(&self) -> BybitHttpClient

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> PolicyExt for T
where T: ?Sized,

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] only if self and other return Action::Follow. Read more
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns [Action::Follow] if either self or other returns Action::Follow. Read more
§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more