@@ -46,12 +46,9 @@ use nautilus_core::{
4646} ;
4747use nautilus_data:: client:: DataClient ;
4848use nautilus_model:: {
49- currencies:: CURRENCY_MAP ,
5049 data:: Data ,
51- enums:: CurrencyType ,
52- identifiers:: { ClientId , InstrumentId , Symbol , Venue } ,
53- instruments:: { CryptoPerpetual , CurrencyPair , Instrument , InstrumentAny } ,
54- types:: { Currency , Price , Quantity } ,
50+ identifiers:: { ClientId , InstrumentId , Venue } ,
51+ instruments:: { Instrument , InstrumentAny } ,
5552} ;
5653use tokio:: task:: JoinHandle ;
5754use tokio_util:: sync:: CancellationToken ;
@@ -62,102 +59,10 @@ use crate::{
6259 credential:: { EvmPrivateKey , Secrets } ,
6360 } ,
6461 config:: HyperliquidDataClientConfig ,
65- http:: {
66- client:: HyperliquidHttpClient ,
67- parse:: { HyperliquidInstrumentDef , HyperliquidMarketType } ,
68- } ,
62+ http:: client:: HyperliquidHttpClient ,
6963 websocket:: client:: HyperliquidWebSocketClient ,
7064} ;
7165
72- /// Returns a currency, either from the internal currency map or creates a default crypto.
73- fn get_currency ( code : & str ) -> Currency {
74- // SAFETY: Mutex should not be poisoned in normal operation
75- CURRENCY_MAP
76- . lock ( )
77- . expect ( "Failed to acquire CURRENCY_MAP lock" )
78- . get ( code)
79- . copied ( )
80- . unwrap_or ( Currency :: new ( code, 8 , 0 , code, CurrencyType :: Crypto ) )
81- }
82-
83- /// Creates a Nautilus instrument from a Hyperliquid instrument definition.
84- fn create_instrument_from_def ( def : & HyperliquidInstrumentDef ) -> Option < InstrumentAny > {
85- let ts_event = get_atomic_clock_realtime ( ) . get_time_ns ( ) ;
86- let ts_init = ts_event;
87-
88- // Create instrument ID from the symbol
89- let symbol = Symbol :: new ( & def. symbol ) ;
90- let venue = Venue :: new ( "HYPERLIQUID" ) ;
91- let instrument_id = InstrumentId :: new ( symbol, venue) ;
92-
93- let raw_symbol = Symbol :: new ( & def. symbol ) ;
94- let base_currency = get_currency ( & def. base ) ;
95- let quote_currency = get_currency ( & def. quote ) ;
96- let price_increment = Price :: from ( & def. tick_size . to_string ( ) ) ;
97- let size_increment = Quantity :: from ( & def. lot_size . to_string ( ) ) ;
98-
99- // For now, use minimal parameters - no fees, margins, or lot sizes
100- match def. market_type {
101- HyperliquidMarketType :: Spot => {
102- Some ( InstrumentAny :: CurrencyPair ( CurrencyPair :: new (
103- instrument_id,
104- raw_symbol,
105- base_currency,
106- quote_currency,
107- def. price_decimals as u8 ,
108- def. size_decimals as u8 ,
109- price_increment,
110- size_increment,
111- None , // multiplier
112- None , // lot_size
113- None , // max_quantity
114- None , // min_quantity
115- None , // max_notional
116- None , // min_notional
117- None , // max_price
118- None , // min_price
119- None , // margin_init
120- None , // margin_maint
121- None , // maker_fee
122- None , // taker_fee
123- ts_event,
124- ts_init,
125- ) ) )
126- }
127- HyperliquidMarketType :: Perp => {
128- // For Hyperliquid, perps are USD-quoted and USDC-settled
129- let settlement_currency = get_currency ( "USDC" ) ;
130-
131- Some ( InstrumentAny :: CryptoPerpetual ( CryptoPerpetual :: new (
132- instrument_id,
133- raw_symbol,
134- base_currency,
135- quote_currency,
136- settlement_currency,
137- false , // is_inverse - Hyperliquid perps are linear
138- def. price_decimals as u8 ,
139- def. size_decimals as u8 ,
140- price_increment,
141- size_increment,
142- None , // multiplier
143- None , // lot_size
144- None , // max_quantity
145- None , // min_quantity
146- None , // max_notional
147- None , // min_notional
148- None , // max_price
149- None , // min_price
150- None , // margin_init
151- None , // margin_maint
152- None , // maker_fee
153- None , // taker_fee
154- ts_event,
155- ts_init,
156- ) ) )
157- }
158- }
159- }
160-
16166#[ derive( Debug ) ]
16267pub struct HyperliquidDataClient {
16368 client_id : ClientId ,
@@ -227,24 +132,20 @@ impl HyperliquidDataClient {
227132 }
228133
229134 async fn bootstrap_instruments ( & mut self ) -> Result < Vec < InstrumentAny > > {
230- let mut instruments = Vec :: new ( ) ;
231-
232- match self . http_client . request_instruments ( ) . await {
233- Ok ( defs) => {
135+ let instruments = match self . http_client . request_instruments ( ) . await {
136+ Ok ( mut instruments) => {
234137 tracing:: debug!(
235- count = defs . len( ) ,
236- "Received Hyperliquid instrument definitions "
138+ count = instruments . len( ) ,
139+ "Received Hyperliquid instruments "
237140 ) ;
238- for def in defs {
239- if let Some ( instrument) = create_instrument_from_def ( & def) {
240- instruments. push ( instrument) ;
241- }
242- }
141+ instruments. sort_by_key ( |instrument| instrument. id ( ) ) ;
142+ instruments
243143 }
244144 Err ( err) => {
245145 tracing:: warn!( %err, "Failed to request Hyperliquid instruments" ) ;
146+ Vec :: new ( )
246147 }
247- }
148+ } ;
248149
249150 tracing:: info!( count = instruments. len( ) , "Loaded Hyperliquid instruments" ) ;
250151
0 commit comments