Class: Hyperliquid::Exchange
- Inherits:
-
Object
- Object
- Hyperliquid::Exchange
- Defined in:
- lib/hyperliquid/exchange.rb
Overview
Exchange API client for write operations (orders, cancels, etc.) Requires a private key for signing transactions
Constant Summary collapse
- DEFAULT_SLIPPAGE =
Default slippage for market orders (5%)
0.05- SPOT_ASSET_THRESHOLD =
Spot assets have indices >= 10000
10_000
Instance Method Summary collapse
-
#address ⇒ String
Get the wallet address.
-
#bulk_cancel(cancels:, vault_address: nil) ⇒ Hash
Cancel multiple orders by order ID.
-
#bulk_cancel_by_cloid(cancels:, vault_address: nil) ⇒ Hash
Cancel multiple orders by client order ID.
-
#bulk_orders(orders:, grouping: 'na', vault_address: nil) ⇒ Hash
Place multiple orders in a batch.
-
#cancel(coin:, oid:, vault_address: nil) ⇒ Hash
Cancel a single order by order ID.
-
#cancel_by_cloid(coin:, cloid:, vault_address: nil) ⇒ Hash
Cancel a single order by client order ID.
-
#initialize(client:, signer:, info:, expires_after: nil) ⇒ Exchange
constructor
Initialize the exchange client.
-
#market_order(coin:, is_buy:, size:, slippage: DEFAULT_SLIPPAGE, vault_address: nil) ⇒ Hash
Place a market order (aggressive limit IoC with slippage).
-
#order(coin:, is_buy:, size:, limit_px:, order_type: { limit: { tif: 'Gtc' } }, reduce_only: false, cloid: nil, vault_address: nil) ⇒ Hash
Place a single order.
-
#reload_metadata! ⇒ Object
Clear the asset metadata cache Call this if metadata has been updated.
Constructor Details
#initialize(client:, signer:, info:, expires_after: nil) ⇒ Exchange
Initialize the exchange client
20 21 22 23 24 25 26 |
# File 'lib/hyperliquid/exchange.rb', line 20 def initialize(client:, signer:, info:, expires_after: nil) @client = client @signer = signer @info = info @expires_after = expires_after @asset_cache = nil end |
Instance Method Details
#address ⇒ String
Get the wallet address
30 31 32 |
# File 'lib/hyperliquid/exchange.rb', line 30 def address @signer.address end |
#bulk_cancel(cancels:, vault_address: nil) ⇒ Hash
Cancel multiple orders by order ID
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/hyperliquid/exchange.rb', line 180 def bulk_cancel(cancels:, vault_address: nil) nonce = cancel_wires = cancels.map do |c| { a: asset_index(c[:coin]), o: c[:oid] } end action = { type: 'cancel', cancels: cancel_wires } signature = @signer.sign_l1_action( action, nonce, vault_address: vault_address, expires_after: @expires_after ) post_action(action, signature, nonce, vault_address) end |
#bulk_cancel_by_cloid(cancels:, vault_address: nil) ⇒ Hash
Cancel multiple orders by client order ID
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/hyperliquid/exchange.rb', line 200 def bulk_cancel_by_cloid(cancels:, vault_address: nil) nonce = cancel_wires = cancels.map do |c| { asset: asset_index(c[:coin]), cloid: normalize_cloid(c[:cloid]) } end action = { type: 'cancelByCloid', cancels: cancel_wires } signature = @signer.sign_l1_action( action, nonce, vault_address: vault_address, expires_after: @expires_after ) post_action(action, signature, nonce, vault_address) end |
#bulk_orders(orders:, grouping: 'na', vault_address: nil) ⇒ Hash
Place multiple orders in a batch
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/hyperliquid/exchange.rb', line 78 def bulk_orders(orders:, grouping: 'na', vault_address: nil) nonce = order_wires = orders.map do |o| build_order_wire( coin: o[:coin], is_buy: o[:is_buy], size: o[:size], limit_px: o[:limit_px], order_type: o[:order_type] || { limit: { tif: 'Gtc' } }, reduce_only: o[:reduce_only] || false, cloid: o[:cloid] ) end action = { type: 'order', orders: order_wires, grouping: grouping } signature = @signer.sign_l1_action( action, nonce, vault_address: vault_address, expires_after: @expires_after ) post_action(action, signature, nonce, vault_address) end |
#cancel(coin:, oid:, vault_address: nil) ⇒ Hash
Cancel a single order by order ID
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
# File 'lib/hyperliquid/exchange.rb', line 138 def cancel(coin:, oid:, vault_address: nil) nonce = action = { type: 'cancel', cancels: [{ a: asset_index(coin), o: oid }] } signature = @signer.sign_l1_action( action, nonce, vault_address: vault_address, expires_after: @expires_after ) post_action(action, signature, nonce, vault_address) end |
#cancel_by_cloid(coin:, cloid:, vault_address: nil) ⇒ Hash
Cancel a single order by client order ID
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/hyperliquid/exchange.rb', line 159 def cancel_by_cloid(coin:, cloid:, vault_address: nil) nonce = cloid_raw = normalize_cloid(cloid) action = { type: 'cancelByCloid', cancels: [{ asset: asset_index(coin), cloid: cloid_raw }] } signature = @signer.sign_l1_action( action, nonce, vault_address: vault_address, expires_after: @expires_after ) post_action(action, signature, nonce, vault_address) end |
#market_order(coin:, is_buy:, size:, slippage: DEFAULT_SLIPPAGE, vault_address: nil) ⇒ Hash
Place a market order (aggressive limit IoC with slippage)
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/hyperliquid/exchange.rb', line 114 def market_order(coin:, is_buy:, size:, slippage: DEFAULT_SLIPPAGE, vault_address: nil) # Get current mid price mids = @info.all_mids mid = mids[coin]&.to_f raise ArgumentError, "Unknown asset or no price available: #{coin}" unless mid&.positive? # Apply slippage and round to appropriate precision slippage_price = calculate_slippage_price(coin, mid, is_buy, slippage) order( coin: coin, is_buy: is_buy, size: size, limit_px: slippage_price, order_type: { limit: { tif: 'Ioc' } }, vault_address: vault_address ) end |
#order(coin:, is_buy:, size:, limit_px:, order_type: { limit: { tif: 'Gtc' } }, reduce_only: false, cloid: nil, vault_address: nil) ⇒ Hash
Place a single order
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/hyperliquid/exchange.rb', line 44 def order(coin:, is_buy:, size:, limit_px:, order_type: { limit: { tif: 'Gtc' } }, reduce_only: false, cloid: nil, vault_address: nil) nonce = order_wire = build_order_wire( coin: coin, is_buy: is_buy, size: size, limit_px: limit_px, order_type: order_type, reduce_only: reduce_only, cloid: cloid ) action = { type: 'order', orders: [order_wire], grouping: 'na' } signature = @signer.sign_l1_action( action, nonce, vault_address: vault_address, expires_after: @expires_after ) post_action(action, signature, nonce, vault_address) end |
#reload_metadata! ⇒ Object
Clear the asset metadata cache Call this if metadata has been updated
218 219 220 |
# File 'lib/hyperliquid/exchange.rb', line 218 def @asset_cache = nil end |