deribit_base/model/
funding.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 21/7/25
5******************************************************************************/
6
7use crate::{impl_json_debug_pretty, impl_json_display};
8use serde::{Deserialize, Serialize};
9
10/// Funding chart data structure
11#[derive(Clone, Serialize, Deserialize)]
12pub struct FundingChartData {
13    /// Current interest rate
14    pub current_interest: f64,
15    /// 8h interest rate
16    pub interest_8h: f64,
17    /// Historical funding data points
18    pub data: Vec<FundingDataPoint>,
19}
20
21impl FundingChartData {
22    /// Create new funding chart data
23    pub fn new() -> Self {
24        Self {
25            current_interest: 0.0,
26            interest_8h: 0.0,
27            data: Vec::new(),
28        }
29    }
30}
31
32impl Default for FundingChartData {
33    fn default() -> Self {
34        Self::new()
35    }
36}
37
38impl_json_display!(FundingChartData);
39impl_json_debug_pretty!(FundingChartData);
40
41/// Funding data point structure
42#[derive(Clone, Serialize, Deserialize)]
43pub struct FundingDataPoint {
44    /// Index price at the time
45    pub index_price: f64,
46    /// 8h interest rate
47    pub interest_8h: f64,
48    /// Timestamp of the data point
49    pub timestamp: u64,
50}
51
52impl FundingDataPoint {
53    /// Create new funding data point
54    pub fn new(index_price: f64, interest_8h: f64, timestamp: u64) -> Self {
55        Self {
56            index_price,
57            interest_8h,
58            timestamp,
59        }
60    }
61}
62
63impl_json_display!(FundingDataPoint);
64impl_json_debug_pretty!(FundingDataPoint);
65
66/// Funding rate data structure for historical funding rates
67#[derive(Clone, Serialize, Deserialize)]
68pub struct FundingRateData {
69    /// Timestamp of the funding event
70    pub timestamp: u64,
71    /// Index price at the time
72    pub index_price: f64,
73    /// 8h interest rate
74    pub interest_8h: f64,
75    /// 1h interest rate
76    pub interest_1h: f64,
77    /// Previous index price
78    pub prev_index_price: f64,
79}
80
81impl FundingRateData {
82    /// Create new funding rate data
83    pub fn new(
84        timestamp: u64,
85        index_price: f64,
86        interest_8h: f64,
87        interest_1h: f64,
88        prev_index_price: f64,
89    ) -> Self {
90        Self {
91            timestamp,
92            index_price,
93            interest_8h,
94            interest_1h,
95            prev_index_price,
96        }
97    }
98}
99
100impl_json_display!(FundingRateData);
101impl_json_debug_pretty!(FundingRateData);
102
103/// TradingView chart data structure
104#[derive(Clone, Serialize, Deserialize)]
105pub struct TradingViewChartData {
106    /// Status of the data
107    pub status: String,
108    /// Array of timestamps
109    pub ticks: Vec<u64>,
110    /// Array of open prices
111    pub open: Vec<f64>,
112    /// Array of high prices
113    pub high: Vec<f64>,
114    /// Array of low prices
115    pub low: Vec<f64>,
116    /// Array of close prices
117    pub close: Vec<f64>,
118    /// Array of volumes
119    pub volume: Vec<f64>,
120    /// Array of costs
121    pub cost: Vec<f64>,
122}
123
124impl TradingViewChartData {
125    /// Create new TradingView chart data
126    pub fn new() -> Self {
127        Self {
128            status: "ok".to_string(),
129            ticks: Vec::new(),
130            open: Vec::new(),
131            high: Vec::new(),
132            low: Vec::new(),
133            close: Vec::new(),
134            volume: Vec::new(),
135            cost: Vec::new(),
136        }
137    }
138
139    /// Add a new candle to the data
140    #[allow(clippy::too_many_arguments)]
141    pub fn add_candle(
142        &mut self,
143        timestamp: u64,
144        open: f64,
145        high: f64,
146        low: f64,
147        close: f64,
148        volume: f64,
149        cost: f64,
150    ) {
151        self.ticks.push(timestamp);
152        self.open.push(open);
153        self.high.push(high);
154        self.low.push(low);
155        self.close.push(close);
156        self.volume.push(volume);
157        self.cost.push(cost);
158    }
159}
160
161impl Default for TradingViewChartData {
162    fn default() -> Self {
163        Self::new()
164    }
165}
166
167impl_json_display!(TradingViewChartData);
168impl_json_debug_pretty!(TradingViewChartData);
169
170#[cfg(test)]
171mod tests {
172    use super::*;
173
174    #[test]
175    fn test_funding_chart_data_creation() {
176        let chart_data = FundingChartData::new();
177        assert_eq!(chart_data.current_interest, 0.0);
178        assert_eq!(chart_data.interest_8h, 0.0);
179        assert!(chart_data.data.is_empty());
180    }
181
182    #[test]
183    fn test_trading_view_chart_data_creation() {
184        let mut chart_data = TradingViewChartData::new();
185        chart_data.add_candle(
186            1640995200000, // timestamp
187            45000.0,       // open
188            45500.0,       // high
189            44800.0,       // low
190            45200.0,       // close
191            100.0,         // volume
192            4520000.0,     // cost
193        );
194
195        assert_eq!(chart_data.ticks.len(), 1);
196        assert_eq!(chart_data.open[0], 45000.0);
197        assert_eq!(chart_data.high[0], 45500.0);
198    }
199
200    #[test]
201    fn test_serde() {
202        let funding_data = FundingRateData::new(
203            1640995200000, // timestamp
204            45000.0,       // index_price
205            0.0001,        // interest_8h
206            0.00001,       // interest_1h
207            44900.0,       // prev_index_price
208        );
209
210        let json = serde_json::to_string(&funding_data).unwrap();
211        let deserialized: FundingRateData = serde_json::from_str(&json).unwrap();
212        assert_eq!(funding_data.timestamp, deserialized.timestamp);
213        assert_eq!(funding_data.index_price, deserialized.index_price);
214    }
215}