ccxt_exchanges/binance/parser/
funding.rs1#![allow(dead_code)]
2
3use super::{parse_decimal, parse_f64};
4use ccxt_core::{
5 Result,
6 error::{Error, ParseError},
7 types::{
8 FeeFundingRate, FeeFundingRateHistory, FundingFee, FundingHistory, Market, NextFundingRate,
9 },
10};
11use serde_json::Value;
12
13pub fn parse_funding_rate(data: &Value, market: Option<&Market>) -> Result<FeeFundingRate> {
15 let symbol = if let Some(m) = market {
16 m.symbol.clone()
17 } else {
18 data["symbol"]
19 .as_str()
20 .ok_or_else(|| Error::from(ParseError::missing_field("symbol")))?
21 .to_string()
22 };
23
24 let funding_rate =
25 parse_decimal(data, "lastFundingRate").or_else(|| parse_decimal(data, "fundingRate"));
26
27 let mark_price = parse_decimal(data, "markPrice");
28 let index_price = parse_decimal(data, "indexPrice");
29 let interest_rate = parse_decimal(data, "interestRate");
30
31 let next_funding_time = data["nextFundingTime"].as_i64();
32 let funding_timestamp = next_funding_time.or_else(|| data["fundingTime"].as_i64());
33
34 Ok(FeeFundingRate {
35 info: data.clone(),
36 symbol,
37 mark_price,
38 index_price,
39 interest_rate,
40 estimated_settle_price: None,
41 funding_rate,
42 funding_timestamp,
43 funding_datetime: funding_timestamp
44 .and_then(|t| chrono::DateTime::from_timestamp(t / 1000, 0).map(|dt| dt.to_rfc3339())),
45 next_funding_rate: None,
46 next_funding_timestamp: None,
47 next_funding_datetime: None,
48 previous_funding_rate: None,
49 previous_funding_timestamp: None,
50 previous_funding_datetime: None,
51 timestamp: None,
52 datetime: None,
53 interval: None,
54 })
55}
56
57pub fn parse_funding_rate_history(
59 data: &Value,
60 market: Option<&Market>,
61) -> Result<FeeFundingRateHistory> {
62 let symbol = if let Some(m) = market {
63 m.symbol.clone()
64 } else {
65 data["symbol"]
66 .as_str()
67 .ok_or_else(|| Error::from(ParseError::missing_field("symbol")))?
68 .to_string()
69 };
70
71 let funding_rate = parse_decimal(data, "fundingRate");
72 let funding_time = data["fundingTime"].as_i64();
73
74 Ok(FeeFundingRateHistory {
75 info: data.clone(),
76 symbol,
77 funding_rate,
78 funding_timestamp: funding_time,
79 funding_datetime: funding_time
80 .and_then(|t| chrono::DateTime::from_timestamp(t / 1000, 0).map(|dt| dt.to_rfc3339())),
81 timestamp: funding_time,
82 datetime: funding_time
83 .and_then(|t| chrono::DateTime::from_timestamp(t / 1000, 0).map(|dt| dt.to_rfc3339())),
84 })
85}
86
87pub fn parse_funding_history(data: &Value, market: Option<&Market>) -> Result<FundingHistory> {
89 let symbol = if let Some(m) = market {
90 m.symbol.clone()
91 } else {
92 data["symbol"]
93 .as_str()
94 .ok_or_else(|| Error::from(ParseError::missing_field("symbol")))?
95 .to_string()
96 };
97
98 let id = data["tranId"]
99 .as_u64()
100 .or_else(|| data["id"].as_u64())
101 .map(|v| v.to_string());
102
103 let amount = parse_f64(data, "income");
104 let code = data["asset"].as_str().map(ToString::to_string);
105 let timestamp = data["time"].as_i64();
106
107 Ok(FundingHistory {
108 info: data.clone(),
109 id,
110 symbol,
111 code,
112 amount,
113 timestamp,
114 datetime: timestamp.map(|t| {
115 chrono::DateTime::from_timestamp(t / 1000, 0)
116 .map(|dt| dt.to_rfc3339())
117 .unwrap_or_default()
118 }),
119 })
120}
121
122pub fn parse_funding_fee(data: &Value, market: Option<&Market>) -> Result<FundingFee> {
124 let symbol = if let Some(m) = market {
125 m.symbol.clone()
126 } else {
127 data["symbol"]
128 .as_str()
129 .ok_or_else(|| Error::from(ParseError::missing_field("symbol")))?
130 .to_string()
131 };
132
133 let income = parse_f64(data, "income").unwrap_or(0.0);
134 let asset = data["asset"]
135 .as_str()
136 .ok_or_else(|| Error::from(ParseError::missing_field("asset")))?
137 .to_string();
138
139 let time = data["time"]
140 .as_i64()
141 .ok_or_else(|| Error::from(ParseError::missing_field("time")))?;
142
143 let funding_rate = parse_f64(data, "fundingRate");
144 let mark_price = parse_f64(data, "markPrice");
145
146 let datetime = Some(
147 chrono::DateTime::from_timestamp(time / 1000, 0)
148 .map(|dt| dt.to_rfc3339())
149 .unwrap_or_default(),
150 );
151
152 Ok(FundingFee {
153 info: data.clone(),
154 symbol,
155 income,
156 asset,
157 time,
158 datetime,
159 funding_rate,
160 mark_price,
161 })
162}
163
164pub fn parse_next_funding_rate(data: &Value, market: &Market) -> Result<NextFundingRate> {
166 let symbol = market.symbol.clone();
167
168 let mark_price = parse_f64(data, "markPrice")
169 .ok_or_else(|| Error::from(ParseError::missing_field("markPrice")))?;
170
171 let index_price = parse_f64(data, "indexPrice");
172
173 let current_funding_rate = parse_f64(data, "lastFundingRate").unwrap_or(0.0);
174
175 let next_funding_rate = parse_f64(data, "interestRate")
176 .or_else(|| parse_f64(data, "estimatedSettlePrice"))
177 .unwrap_or(current_funding_rate);
178
179 let next_funding_time = data["nextFundingTime"]
180 .as_i64()
181 .ok_or_else(|| Error::from(ParseError::missing_field("nextFundingTime")))?;
182
183 let next_funding_datetime = Some(
184 chrono::DateTime::from_timestamp(next_funding_time / 1000, 0)
185 .map(|dt| dt.to_rfc3339())
186 .unwrap_or_default(),
187 );
188
189 Ok(NextFundingRate {
190 info: data.clone(),
191 symbol,
192 mark_price,
193 index_price,
194 current_funding_rate,
195 next_funding_rate,
196 next_funding_time,
197 next_funding_datetime,
198 })
199}