Skip to content

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)
we get:
[{'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'},
  ...
]
What about OHLCV?
    df = hyp.get_trade_bars(
        ticker="BTC",
        start=datetime(2022,12,14),
        end=datetime.now(),
        granularity=Period.DAILY,
        granularity_multiplier=1
    )
    print(df)
we get
              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
We can actually directly invoke the official SDK, but we would have to configure the parameters:
    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) 
which gives:
                  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?

    res = hyp.l2_snapshot(ticker="BTC")
    pprint(res)
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:

res = hyp.meta()
print(res)
Note that the meta endpoint is supported by the official repo's Info object, which can also be obtained using the info object attribute:
res = hyp.info.meta()
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:

res = hyp.user_state()
pprint(res)
res = hyp.info.user_state(address=hyp.address)
pprint(res)
or perps account equity:
eq = await hyp.get_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:

res = hyp.user_funding_history()
fh = hyp.funding_history(coin="SOL")
print(res)
print(fh)

User L1-Action Rate Limits

Some endpoints not specified in their documentation, and not provided in their official SDK is also provided...

res = hyp.user_rate_limit()
print(res)
which gives you your rate limit cap and usage:
{'cumVlm': , 'nRequestsCap': , 'nRequestsUsed': }

Get Perps Summary

We also provide customized endpoints that process single/multiple endpoints:

res = await hyp.get_perps_data()
pprint(res)
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)
We got:
{'status': 'ok', 'response': {'type': 'cancel', 'data': {'statuses': ['success']}}}

Local Copy of Positions

We can maintain a stateful, local copy of the position sizes using websocket subscriptions:

await hyp.keep_book_state()
book = await hyp.get_book()
Any succeeding calls to get_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")
We get:
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)
Alternatively, you can get a WebsocketManager thread instance with:
ws_thread = hyp.init_threaded_ws_manager(start=True)
<WebsocketManager(Thread-1, started daemon 123145528229888)
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:

  • "baseAsset" str : The base asset symbol.
  • "fr" float : Funding rate.
  • "frint" float, Floating point representation of the funding rate.
  • "marginAsset" str, The margin asset symbol.
  • "markPrice" float, The mark price.
  • "minQty" Decimal, The minimum quantity.
  • "min_notional" float, The minimum notional value.
  • "next_funding" int, Unix timestamp of the next funding, milliseconds.
  • "pricePrecision" Decimal, The price precision.
  • "quantityPrecision" Decimal, The quantity precision.
  • "quoteAsset" str, The quote asset symbol.
  • "stepSize" Decimal, The step size.
  • "symbol" str, The symbol.
  • "timestamp" int, Unix timestamp of the data retrieval, milliseconds.
  • "exchange" str The exchange code , "hyp"

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