use polyoxide_core::HttpClient;
use crate::{
error::BinanceError,
usdm::{
request::WeightedRequest,
types::{
AggTrade, Depth, DepthLimit, FundingRate, Interval, Kline, OpenInterest, PremiumIndex,
Symbol, Ticker24h,
},
},
weight::{Cost, Route, WeightBudget},
};
#[derive(Debug, Clone)]
pub struct MarketApi {
pub(crate) http: HttpClient,
pub(crate) budget: WeightBudget,
}
impl MarketApi {
fn request<T>(&self, route: Route) -> WeightedRequest<T> {
WeightedRequest::new(&self.http, &self.budget, route)
}
pub fn ticker_24h(&self, symbol: &Symbol) -> WeightedRequest<Ticker24h> {
self.request(Route::Ticker24h { all: false })
.query("symbol", symbol)
}
pub fn tickers_24h(&self) -> WeightedRequest<Vec<Ticker24h>> {
self.request(Route::Ticker24h { all: true })
}
pub fn premium_index(&self, symbol: &Symbol) -> WeightedRequest<PremiumIndex> {
self.request(Route::PremiumIndex { all: false })
.query("symbol", symbol)
}
pub fn premium_indices(&self) -> WeightedRequest<Vec<PremiumIndex>> {
self.request(Route::PremiumIndex { all: true })
}
pub fn klines(&self, symbol: &Symbol, interval: Interval) -> GetKlines {
GetKlines {
request: self
.request(Route::Klines { limit: None })
.query("symbol", symbol)
.query("interval", interval),
}
}
pub fn funding_rate(&self) -> GetFundingRate {
GetFundingRate {
request: self.request(Route::FundingRate),
}
}
pub fn open_interest(&self, symbol: &Symbol) -> WeightedRequest<OpenInterest> {
self.request(Route::OpenInterest).query("symbol", symbol)
}
pub fn agg_trades(&self, symbol: &Symbol) -> GetAggTrades {
GetAggTrades {
request: self.request(Route::AggTrades).query("symbol", symbol),
}
}
pub fn depth(&self, symbol: &Symbol) -> GetDepth {
GetDepth {
request: self
.request(Route::Depth { limit: None })
.query("symbol", symbol),
}
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetKlines {
request: WeightedRequest<Vec<Kline>>,
}
impl GetKlines {
pub fn start_time(mut self, ms: u64) -> Self {
self.request = self.request.query("startTime", ms);
self
}
pub fn end_time(mut self, ms: u64) -> Self {
self.request = self.request.query("endTime", ms);
self
}
pub fn limit(mut self, limit: u32) -> Self {
self.request = self
.request
.route(Route::Klines { limit: Some(limit) })
.query("limit", limit);
self
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Vec<Kline>, BinanceError> {
self.request.send().await
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetFundingRate {
request: WeightedRequest<Vec<FundingRate>>,
}
impl GetFundingRate {
pub fn symbol(mut self, symbol: &Symbol) -> Self {
self.request = self.request.query("symbol", symbol);
self
}
pub fn start_time(mut self, ms: u64) -> Self {
self.request = self.request.query("startTime", ms);
self
}
pub fn end_time(mut self, ms: u64) -> Self {
self.request = self.request.query("endTime", ms);
self
}
pub fn limit(mut self, limit: u32) -> Self {
self.request = self.request.query("limit", limit);
self
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Vec<FundingRate>, BinanceError> {
self.request.send().await
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetAggTrades {
request: WeightedRequest<Vec<AggTrade>>,
}
impl GetAggTrades {
pub fn from_id(mut self, id: u64) -> Self {
self.request = self.request.query("fromId", id);
self
}
pub fn start_time(mut self, ms: u64) -> Self {
self.request = self.request.query("startTime", ms);
self
}
pub fn end_time(mut self, ms: u64) -> Self {
self.request = self.request.query("endTime", ms);
self
}
pub fn limit(mut self, limit: u32) -> Self {
self.request = self.request.query("limit", limit);
self
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Vec<AggTrade>, BinanceError> {
self.request.send().await
}
}
#[must_use = "a request does nothing until it is sent"]
pub struct GetDepth {
request: WeightedRequest<Depth>,
}
impl GetDepth {
pub fn limit(mut self, limit: DepthLimit) -> Self {
self.request = self
.request
.route(Route::Depth { limit: Some(limit) })
.query("limit", limit);
self
}
pub fn cost(&self) -> Cost {
self.request.cost()
}
pub async fn send(self) -> Result<Depth, BinanceError> {
self.request.send().await
}
}