Skip to main content

ccxt_exchanges/bitget/rest/futures/
funding.rs

1//! Funding rate operations for Bitget futures/swap.
2
3use super::super::super::{Bitget, parser, symbol::BitgetSymbolConverter};
4use ccxt_core::{
5    Error, ParseError, Result,
6    types::{FundingRate, FundingRateHistory},
7};
8use std::collections::HashMap;
9use tracing::warn;
10
11impl Bitget {
12    /// Fetch current funding rate for a symbol.
13    ///
14    /// Uses Bitget GET `/api/v2/mix/market/current-fund-rate` (public endpoint).
15    pub async fn fetch_funding_rate_impl(&self, symbol: &str) -> Result<FundingRate> {
16        let exchange_id = BitgetSymbolConverter::unified_to_exchange(symbol);
17        let product_type = BitgetSymbolConverter::product_type_from_symbol(symbol);
18
19        let mut params = HashMap::new();
20        params.insert("symbol".to_string(), exchange_id);
21        params.insert("productType".to_string(), product_type.to_string());
22
23        let data = self
24            .public_request("GET", "/api/v2/mix/market/current-fund-rate", Some(&params))
25            .await?;
26
27        let rates_array = data["data"].as_array().ok_or_else(|| {
28            Error::from(ParseError::invalid_format("data", "Expected data array"))
29        })?;
30
31        if rates_array.is_empty() {
32            return Err(Error::from(ParseError::missing_field_owned(format!(
33                "No funding rate found for symbol: {}",
34                symbol
35            ))));
36        }
37
38        parser::parse_funding_rate(&rates_array[0], symbol)
39    }
40
41    /// Fetch funding rates for multiple symbols.
42    pub async fn fetch_funding_rates_impl(&self, symbols: &[&str]) -> Result<Vec<FundingRate>> {
43        let mut rates = Vec::new();
44        for symbol in symbols {
45            match self.fetch_funding_rate_impl(symbol).await {
46                Ok(rate) => rates.push(rate),
47                Err(e) => {
48                    warn!(error = %e, symbol = %symbol, "Failed to fetch Bitget funding rate");
49                }
50            }
51        }
52        Ok(rates)
53    }
54
55    /// Fetch funding rate history for a symbol.
56    ///
57    /// Uses Bitget GET `/api/v2/mix/market/history-fund-rate` (public endpoint).
58    pub async fn fetch_funding_rate_history_impl(
59        &self,
60        symbol: &str,
61        since: Option<i64>,
62        limit: Option<u32>,
63    ) -> Result<Vec<FundingRateHistory>> {
64        let exchange_id = BitgetSymbolConverter::unified_to_exchange(symbol);
65        let product_type = BitgetSymbolConverter::product_type_from_symbol(symbol);
66
67        let mut params = HashMap::new();
68        params.insert("symbol".to_string(), exchange_id);
69        params.insert("productType".to_string(), product_type.to_string());
70
71        if let Some(l) = limit {
72            params.insert("pageSize".to_string(), l.to_string());
73        }
74
75        if let Some(s) = since {
76            params.insert("startTime".to_string(), s.to_string());
77        }
78
79        let data = self
80            .public_request("GET", "/api/v2/mix/market/history-fund-rate", Some(&params))
81            .await?;
82
83        let history_array = data["data"].as_array().ok_or_else(|| {
84            Error::from(ParseError::invalid_format("data", "Expected data array"))
85        })?;
86
87        let mut history = Vec::new();
88        for item in history_array {
89            match parser::parse_funding_rate_history(item, symbol) {
90                Ok(record) => history.push(record),
91                Err(e) => {
92                    warn!(error = %e, "Failed to parse Bitget funding rate history");
93                }
94            }
95        }
96
97        Ok(history)
98    }
99}