quantpylib.wrappers.whyperliquid
quantpylib.simulator.whyperliquid
module is our wrapper SDK that acts as an extension of the official Hyperliquid Python SDK for perp trading.
The primary extension is asynchronous support for websocket subscriptions to market and user endpoints, as opposed to thread-based framework, providing a less resource intensive and more efficient data streaming process using lightweight coroutines.
The websocket's asynchronous connection and heartbeat is handled internally. In addition,
the official SDK's use of request sessions as object attributes renders it susceptible to connection errors when the remote server terminates the session, as is often observed in sufficiently long-running applications. This extension modifies at runtime the post method in the hyperliquid.api.API
method to renew session connections in the case of such connection errors.
Asynchronous post requests are also added to the mix, supporting common endpoints such as order-submission. The endpoints have been implemented on a need-to basis by users of the repo, so do open Issues in the Github repo for endpoint implementation requests.
We will demonstrate usage of the library. Note that the original Exchange
, Info
and WebsocketManager
objects are retrievable as object attributes to the whyperliquid.Hyperliquid
instance as obj.info
, obj.exchange
, obj.ws_manager
respectively. The ws_manager
is only available after making a call to obj.init_threaded_ws_manager()
with initiates a running daemon thread. We encourage the use of the asynchronous websocket manager instead.
Examples
We would demonstrate some endpoints. For that, let us first make some imports we would like to use
import os
import time
import asyncio
from pprint import pprint
from dotenv import load_dotenv
load_dotenv()
from quantpylib.standards import Period
from quantpylib.wrappers.whyperliquid import Hyperliquid
async def main():
hyp = Hyperliquid(
address=os.getenv("HYP_PUBLIC"),
hyp_key=os.getenv("HYP_KEY"),
)
#...examples go here
if __name__ == "__main__":
import asyncio
asyncio.run(main())
Get Candles, L2-Snapshot
Let us get candles for BTC
on 15m
intervals for the past hour:
candles = hyp.candles_snapshot(
"BTC",
interval="15m",
startms=int(time.time()) * 1000 - 60 * 60 * 1000,
endms=int(time.time()) * 1000
)
pprint(candles)
[{'T': 1713620699999,
'c': '63945.0',
'h': '64033.0',
'i': '15m',
'l': '63915.0',
'n': 760,
'o': '63966.0',
's': 'BTC',
't': 1713619800000,
'v': '34.96701'},
{'T': 1713621599999,
'c': '63896.0',
'h': '63946.0',
'i': '15m',
'l': '63858.0',
'n': 645,
'o': '63946.0',
's': 'BTC',
't': 1713620700000,
'v': '23.20829'},
...
]
df = hyp.get_trade_bars(
ticker="BTC",
start=datetime(2022,12,14),
end=datetime.now(),
granularity=Period.DAILY,
granularity_multiplier=1
)
print(df)
close high low open volume
datetime
2022-12-14 17803.9 18400.0 17659.4 17777.1 0.0
2022-12-15 17351.8 17849.5 17258.0 17804.0 0.0
2022-12-16 16624.1 17528.0 16521.1 17351.9 0.0
2022-12-17 16768.0 16790.0 16571.8 16624.1 0.0
2022-12-18 16730.3 16872.0 16656.0 16768.1 0.0
... ... ... ... ... ...
2024-04-19 63781.0 65458.0 59571.0 63501.0 11136.02491
2024-04-20 64939.0 65397.0 63066.0 63784.0 4341.65875
2024-04-21 64907.0 65721.0 64189.0 64938.0 4474.41357
2024-04-22 66865.0 67349.0 64488.0 64908.0 6675.27388
2024-04-23 66692.0 67219.0 65822.0 66866.0 3585.15962
import pandas as pd
df = pd.DataFrame(hyp.candles_snapshot(
coin="BTC",
interval="1d",
startms=int(datetime(2022,12,14).timestamp()),
endms=int(datetime.now().timestamp() * 1000),
))
print(df)
T c h i l n o s t v
0 1597881599999 11763.9 12037.1 1d 11574.8 0 11962.0 BTC 1597795200000 0.0
1 1597967999999 11857.9 11888.0 1d 11676.0 0 11763.9 BTC 1597881600000 0.0
2 1598054399999 11538.5 11882.7 1d 11491.0 0 11858.5 BTC 1597968000000 0.0
3 1598140799999 11670.5 11689.1 1d 11385.1 0 11538.5 BTC 1598054400000 0.0
4 1598227199999 11654.0 11724.0 1d 11522.2 0 11670.5 BTC 1598140800000 0.0
... ... ... ... .. ... ... ... ... ... ...
1339 1713571199999 63781.0 65458.0 1d 59571.0 160200 63501.0 BTC 1713484800000 11136.02491
1340 1713657599999 64939.0 65397.0 1d 63066.0 86872 63784.0 BTC 1713571200000 4341.65875
1341 1713743999999 64907.0 65721.0 1d 64189.0 92874 64938.0 BTC 1713657600000 4474.41357
1342 1713830399999 66865.0 67349.0 1d 64488.0 126600 64908.0 BTC 1713744000000 6675.27388
1343 1713916799999 66744.0 67219.0 1d 65822.0 78935 66866.0 BTC 1713830400000 3600.46869
What about a snapshot of the order-book?
we get{'coin': 'BTC',
'levels': [[{'n': 2, 'px': '63871.0', 'sz': '0.15751'},
{'n': 2, 'px': '63869.0', 'sz': '0.18002'},
{'n': 3, 'px': '63868.0', 'sz': '0.2234'},
...
{'n': 2, 'px': '63845.0', 'sz': '0.30832'}],
[{'n': 1, 'px': '63872.0', 'sz': '0.02347'},
{'n': 2, 'px': '63873.0', 'sz': '0.30814'},
...
{'n': 1, 'px': '63898.0', 'sz': '0.15551'}]],
'time': 1713624177254}
Universe Metadata
We can get information about all the listed tickers:
Note that themeta
endpoint is supported by the official repo's Info
object, which can also be obtained using the info
object attribute:
This applies to many of the method endpoints - our extension provides parameter supplementation using the object's known
attributes.
For instance...
Retrieve Open Positions, Orders and more...
These two do the same thing, and can retrieve positions and margin/equity information:
or perps account equity: We just provide an endpoint that does not need to explicitly specify the user address, since this is known at object creation.Funding History for Asset and User
Easy, with this:
User L1-Action Rate Limits
Some endpoints not specified in their documentation, and not provided in their official SDK is also provided...
which gives you your rate limit cap and usage:Get Perps Summary
We also provide customized endpoints that process single/multiple endpoints:
which gives:{ ...
'kPEPE': {'baseAsset': 'kPEPE',
'exchange': 'hyp',
'fr': 1.25e-05,
'frint': 1.0,
'marginAsset': 'USDC',
'markPrice': 0.005185,
'minQty': Decimal('1'),
'min_notional': 10.0,
'next_funding': 1713628800000,
'pricePrecision': Decimal('6'),
'quantityPrecision': Decimal('0'),
'quoteAsset': 'USDT',
'stepSize': Decimal('1'),
'symbol': 'kPEPE',
'timestamp': 1713625221000},
'kSHIB': {'baseAsset': 'kSHIB',
'exchange': 'hyp',
'fr': -1.512e-05,
'frint': 1.0,
'marginAsset': 'USDC',
'markPrice': 0.023169,
'minQty': Decimal('1'),
'min_notional': 10.0,
'next_funding': 1713628800000,
'pricePrecision': Decimal('6'),
'quantityPrecision': Decimal('0'),
'quoteAsset': 'USDT',
'stepSize': Decimal('1'),
'symbol': 'kSHIB',
'timestamp': 1713625221000}
}
Make Orders, See Orders, Cancel Orders
The following example makes a limit order for 10 units of PENDLE at a price of 5.40, waits half a second and then cancels all open orders (using the exchange endpoint in the official repo):
await hyp.limit_order(
ticker="PENDLE",
amount=10,
price=5.40,
)
await asyncio.sleep(0.5)
open_orders = hyp.get_open_orders()
cancels = hyp.exchange.bulk_cancel(
cancel_requests=[{"coin":order["coin"], "oid":order["oid"]} for order in open_orders]
)
print(cancels)
Local Copy of Positions
We can maintain a stateful, local copy of the position sizes using websocket subscriptions:
Any succeeding calls toget_book
does not incur network trips and maintains a copy of the account positions.
defaultdict(<function Hyperliquid.get_book.<locals>.<lambda> at 0x10d4316c0>, {'SOL': Decimal('-2070.0'), ...})
Stream L2-Order Book Data
The following code first subscribes to the l2-order book data for BTC, asynchronous-waits for 6 seconds and then prints out the data collected in the buffer, followed by unsubscribing:
await hyp.fut_l2_subscribe(symbol="BTC")
await asyncio.sleep(6)
print(hyp.fut_l2_streamed(symbol="BTC"))
await hyp.fut_l2_unsubscribe(symbol="BTC")
deque([{'ts': 1713625997920, 'b': array([[6.3899e+04, 1.5530e-02],
[6.3898e+04, 3.6000e-01],
[6.3895e+04, 6.0000e-02],
...
[6.3868e+04, 1.5832e-01]]), 'a': array([[6.39000e+04, 1.59168e+00],
...
[6.39440e+04, 3.09920e-01]])},
{'ts': 1713625998823, 'b': array([[6.3899e+04, 1.4180e-02],
[6.3898e+04, 1.8000e-01],
...
])}], maxlen=100)
WebsocketManager
thread instance with:
and the original behavior as implemented in the official repo will apply. This is not the preferred usage. The thread hangs due to the ping thread that loops forever (suspicion) - this is a non-issue in the asynchronous extension.
Documentation
Hyperliquid
__init__(address='', hyp_key=None, buffer_len=100)
Initializes the Hyperliquid instance.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
address |
str
|
The on-chain address in 42-character hexadecimal format. |
''
|
hyp_key |
str
|
The Hyperliquid API key. Defaults to None. |
None
|
buffer_len |
int
|
The maximum length of the stream buffer. Defaults to 100. |
100
|
candles_snapshot(coin, interval, startms, endms)
Retrieve candles snapshot for a given coin.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
coin |
str
|
The coin symbol. |
required |
interval |
str
|
Candlestick interval. |
required |
startms |
int
|
Start time in milliseconds. |
required |
endms |
int
|
End time in milliseconds. |
required |
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#candle-snapshot
clean()
async
Cleans up open sessions with HPL server
frontend_open_orders()
Retrieve a user's open orders with additional frontend info.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-open-orders-with-additional-frontend-info
funding_history(coin, startms=int(datetime.now(pytz.utc) - timedelta(days=14).timestamp() * 1000), endms=None)
Retrieve funding history for a given coin.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
coin |
str
|
The coin symbol. |
required |
startms |
int
|
Start time in milliseconds. Defaults to 14 days ago from the current time. |
int(timestamp() * 1000)
|
endms |
int
|
End time in milliseconds. Defaults to None. |
None
|
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-historical-funding-rates
fut_l2_streamed(symbol)
Retrives the streamed l2-order book data from the stream buffer.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
symbol |
str
|
Ticker symbol for the perpetual asset. |
required |
fut_l2_subscribe(symbol, stream_buffer=None, handler=None)
async
Stream l2-order book market data for given coin. L2 websocket pushes out at the later of 0.5 second or an orderbook change (in a new block).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
symbol |
str
|
Ticker symbol for the perpetual asset. |
required |
stream_buffer |
(Union[Deque, defaultdict], Optional)
|
A data structure that stores streaming data. Deque instance contains streamed data. Uses internal buffer if not given. |
None
|
fut_l2_subscriptions()
Retrieve the list of perpetuals with open subscription.
fut_l2_unsubscribe(symbol)
async
Terminate stream for coin l2-order book.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
symbol |
str
|
Ticker symbol for the perpetual asset. |
required |
get_book()
async
Returns the address's { coin : Decimal(coin_pos) }
.
Should only be called after keep_book_state
has been initiated.
get_equity()
async
Retrieve the perpetual account equity of the user.
Returns:
Name | Type | Description |
---|---|---|
float |
The equity of the user. |
get_open_orders()
Retrieve the details of account's all open orders.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-open-orders
get_perps_data(in_decimal=True)
async
Retrieve perpetuals data.
Returns:
Type | Description |
---|---|
dict
|
A dictionary containing symbol to perp data with the following perp data structure:
|
get_trade_bars(ticker, start, end, granularity, granularity_multiplier, kline_close=False, **kwargs)
Retrieve trade bars data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
ticker |
str
|
Ticker symbol for the asset. |
required |
start |
datetime
|
Start datetime for the data retrieval. |
required |
end |
datetime
|
End datetime for the data retrieval. |
required |
granularity |
Period
|
Granularity of the data. |
required |
granularity_multiplier |
int
|
Multiplier for the granularity. |
required |
exchange |
str
|
Exchange name. Defaults to "US". |
required |
**kwargs |
Additional keyword arguments. |
{}
|
Returns:
Type | Description |
---|---|
DataFrame
|
DataFrame containing the trade bars data. |
init_threaded_ws_manager(start=True)
Initializes the Threaded WebSocket manager thread in daemon mode.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start |
bool
|
Whether to start the WebSocket manager thread. Defaults to True. |
True
|
Returns:
Type | Description |
---|---|
WebsocketManager
|
The WebSocket manager instance. |
keep_book_state(handler=None)
async
Keeps a stateful position dictionary using a websocket connection.
Following calls to get_book
returns the address's { coin : Decimal(coin_pos) }
without HTTP requests.
l2_snapshot(ticker, nsigfig=None, depth=None)
async
Retrieve L2 snapshot for a given coin.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
coin |
str
|
The coin symbol. |
required |
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#l2-book-snapshot
limit_order(ticker, amount, price, tif='Gtc', reduce_only=False, **kwargs)
async
Place a limit order.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
ticker |
str
|
The coin symbol. |
required |
amount |
float
|
The (positive or negative) amount to trade. |
required |
price |
float
|
The price at which to execute the order. |
required |
tif |
str
|
The time in force. Defaults to "Gtc". |
'Gtc'
|
reduce_only |
bool
|
Whether the order should reduce an existing position only. Defaults to False. |
False
|
Returns:
Name | Type | Description |
---|---|---|
Any |
The result of the order placement. |
meta()
Retrieve exchange perpetual metadata.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-metadata
query_order_by_oid(oid)
Retrieve the details for the order using its order id.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
oid |
str
|
The order ID. |
required |
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#query-order-status-by-oid-or-cloid
spot_meta()
Retrieve exchange spot metadata.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-perpetuals-metadata
spot_user_state()
Retrieve trading details about a user in the spot market.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/spot#retrieve-a-users-token-balances
user_fills()
Retrieve a given user's fills.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#retrieve-a-users-fills
user_funding_history(startms=int(datetime.now(pytz.utc) - timedelta(days=14).timestamp() * 1000), endms=None)
Retrieve a user's funding history.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
startms |
int
|
Start time in milliseconds. Defaults to 14 days ago from the current time. |
int(timestamp() * 1000)
|
endms |
int
|
End time in milliseconds. Defaults to None. |
None
|
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-a-users-funding-history
user_rate_limit()
Retrieve the user's L1 Rate limits.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits
user_state()
Retrieve trading details about a user.
Notes
https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals#retrieve-users-perpetuals-account-summary