@@ -37,6 +37,7 @@ use nautilus_model::{
3737} ;
3838use nautilus_network:: {
3939 http:: { HttpClient , Method } ,
40+ ratelimiter:: quota:: Quota ,
4041 retry:: { RetryConfig , RetryManager } ,
4142} ;
4243use serde:: { Serialize , de:: DeserializeOwned } ;
@@ -59,7 +60,11 @@ use super::{
5960} ;
6061use crate :: {
6162 common:: {
62- consts:: { DERIBIT_API_PATH , JSONRPC_VERSION , should_retry_error_code} ,
63+ consts:: {
64+ DERIBIT_ACCOUNT_RATE_KEY , DERIBIT_API_PATH , DERIBIT_GLOBAL_RATE_KEY ,
65+ DERIBIT_HTTP_ACCOUNT_QUOTA , DERIBIT_HTTP_ORDER_QUOTA , DERIBIT_HTTP_REST_QUOTA ,
66+ DERIBIT_ORDER_RATE_KEY , JSONRPC_VERSION , should_retry_error_code,
67+ } ,
6368 credential:: Credential ,
6469 parse:: {
6570 extract_server_timestamp, parse_account_state, parse_bars,
@@ -128,10 +133,10 @@ impl DeribitRawHttpClient {
128133 Ok ( Self {
129134 base_url,
130135 client : HttpClient :: new (
131- HashMap :: new ( ) , // headers
132- Vec :: new ( ) , // header_keys
133- Vec :: new ( ) , // keyed_quotas
134- None , // default_quota
136+ HashMap :: new ( ) ,
137+ Vec :: new ( ) ,
138+ Self :: rate_limiter_quotas ( ) ,
139+ Some ( * DERIBIT_HTTP_REST_QUOTA ) ,
135140 timeout_secs,
136141 proxy_url,
137142 )
@@ -154,6 +159,80 @@ impl DeribitRawHttpClient {
154159 self . base_url . contains ( "test" )
155160 }
156161
162+ /// Returns the rate limiter quotas for the HTTP client.
163+ ///
164+ /// Quotas are organized by:
165+ /// - Global: Overall rate limit for all requests
166+ /// - Orders: Matching engine operations (buy, sell, cancel, etc.)
167+ /// - Account: Account information endpoints
168+ fn rate_limiter_quotas ( ) -> Vec < ( String , Quota ) > {
169+ vec ! [
170+ (
171+ DERIBIT_GLOBAL_RATE_KEY . to_string( ) ,
172+ * DERIBIT_HTTP_REST_QUOTA ,
173+ ) ,
174+ (
175+ DERIBIT_ORDER_RATE_KEY . to_string( ) ,
176+ * DERIBIT_HTTP_ORDER_QUOTA ,
177+ ) ,
178+ (
179+ DERIBIT_ACCOUNT_RATE_KEY . to_string( ) ,
180+ * DERIBIT_HTTP_ACCOUNT_QUOTA ,
181+ ) ,
182+ ]
183+ }
184+
185+ /// Returns rate limit keys for a given RPC method.
186+ ///
187+ /// Maps Deribit JSON-RPC methods to appropriate rate limit buckets.
188+ fn rate_limit_keys ( method : & str ) -> Vec < String > {
189+ let mut keys = vec ! [ DERIBIT_GLOBAL_RATE_KEY . to_string( ) ] ;
190+
191+ // Categorize by method type
192+ if Self :: is_order_method ( method) {
193+ keys. push ( DERIBIT_ORDER_RATE_KEY . to_string ( ) ) ;
194+ } else if Self :: is_account_method ( method) {
195+ keys. push ( DERIBIT_ACCOUNT_RATE_KEY . to_string ( ) ) ;
196+ }
197+
198+ // Add method-specific key
199+ keys. push ( format ! ( "deribit:{method}" ) ) ;
200+
201+ keys
202+ }
203+
204+ /// Returns true if the method is an order operation (matching engine).
205+ fn is_order_method ( method : & str ) -> bool {
206+ matches ! (
207+ method,
208+ "private/buy"
209+ | "private/sell"
210+ | "private/edit"
211+ | "private/cancel"
212+ | "private/cancel_all"
213+ | "private/cancel_all_by_currency"
214+ | "private/cancel_all_by_instrument"
215+ | "private/cancel_by_label"
216+ | "private/close_position"
217+ )
218+ }
219+
220+ /// Returns true if the method accesses account information.
221+ fn is_account_method ( method : & str ) -> bool {
222+ matches ! (
223+ method,
224+ "private/get_account_summaries"
225+ | "private/get_account_summary"
226+ | "private/get_positions"
227+ | "private/get_position"
228+ | "private/get_open_orders_by_currency"
229+ | "private/get_open_orders_by_instrument"
230+ | "private/get_order_state"
231+ | "private/get_user_trades_by_currency"
232+ | "private/get_user_trades_by_instrument"
233+ )
234+ }
235+
157236 /// Creates a new [`DeribitRawHttpClient`] with explicit credentials.
158237 ///
159238 /// # Errors
@@ -192,8 +271,8 @@ impl DeribitRawHttpClient {
192271 client : HttpClient :: new (
193272 HashMap :: new ( ) ,
194273 Vec :: new ( ) ,
195- Vec :: new ( ) ,
196- None ,
274+ Self :: rate_limiter_quotas ( ) ,
275+ Some ( * DERIBIT_HTTP_REST_QUOTA ) ,
197276 timeout_secs,
198277 proxy_url,
199278 )
@@ -308,6 +387,7 @@ impl DeribitRawHttpClient {
308387 headers. extend ( auth_headers) ;
309388 }
310389
390+ let rate_limit_keys = Self :: rate_limit_keys ( & method) ;
311391 let resp = self
312392 . client
313393 . request (
@@ -317,7 +397,7 @@ impl DeribitRawHttpClient {
317397 Some ( headers) ,
318398 Some ( body) ,
319399 None ,
320- None ,
400+ Some ( rate_limit_keys ) ,
321401 )
322402 . await
323403 . map_err ( |e| DeribitHttpError :: NetworkError ( e. to_string ( ) ) ) ?;
@@ -1456,3 +1536,41 @@ impl DeribitHttpClient {
14561536 Ok ( reports)
14571537 }
14581538}
1539+
1540+ #[ cfg( test) ]
1541+ mod tests {
1542+ use rstest:: rstest;
1543+
1544+ use super :: * ;
1545+ use crate :: common:: consts:: {
1546+ DERIBIT_ACCOUNT_RATE_KEY , DERIBIT_GLOBAL_RATE_KEY , DERIBIT_ORDER_RATE_KEY ,
1547+ } ;
1548+
1549+ #[ rstest]
1550+ #[ case( "private/buy" , true , false ) ]
1551+ #[ case( "private/cancel" , true , false ) ]
1552+ #[ case( "private/get_account_summaries" , false , true ) ]
1553+ #[ case( "private/get_positions" , false , true ) ]
1554+ #[ case( "public/get_instruments" , false , false ) ]
1555+ fn test_method_classification (
1556+ #[ case] method : & str ,
1557+ #[ case] is_order : bool ,
1558+ #[ case] is_account : bool ,
1559+ ) {
1560+ assert_eq ! ( DeribitRawHttpClient :: is_order_method( method) , is_order) ;
1561+ assert_eq ! ( DeribitRawHttpClient :: is_account_method( method) , is_account) ;
1562+ }
1563+
1564+ #[ rstest]
1565+ #[ case( "private/buy" , vec![ DERIBIT_GLOBAL_RATE_KEY , DERIBIT_ORDER_RATE_KEY ] ) ]
1566+ #[ case( "private/get_account_summaries" , vec![ DERIBIT_GLOBAL_RATE_KEY , DERIBIT_ACCOUNT_RATE_KEY ] ) ]
1567+ #[ case( "public/get_instruments" , vec![ DERIBIT_GLOBAL_RATE_KEY ] ) ]
1568+ fn test_rate_limit_keys ( #[ case] method : & str , #[ case] expected_keys : Vec < & str > ) {
1569+ let keys = DeribitRawHttpClient :: rate_limit_keys ( method) ;
1570+
1571+ for key in & expected_keys {
1572+ assert ! ( keys. contains( & key. to_string( ) ) ) ;
1573+ }
1574+ assert ! ( keys. contains( & format!( "deribit:{method}" ) ) ) ;
1575+ }
1576+ }
0 commit comments