Example: Placing and Canceling Orders

This example covers the fundamental actions of placing a limit order, querying its status, and then canceling it.

Full Code (examples/basic_order.py)

import json

import example_utils

from hyperliquid.utils import constants

def main():
    address, info, exchange = example_utils.setup(base_url=constants.TESTNET_API_URL, skip_ws=True)

    # Get the user state and print out position information
    user_state = info.user_state(address)
    positions = []
    for position in user_state["assetPositions"]:
        positions.append(position["position"])
    if len(positions) > 0:
        print("positions:")
        for position in positions:
            print(json.dumps(position, indent=2))
    else:
        print("no open positions")

    # Place an order that should rest by setting the price very low
    order_result = exchange.order("ETH", True, 0.2, 1100, {"limit": {"tif": "Gtc"}})
    print(order_result)

    # Query the order status by oid
    if order_result["status"] == "ok":
        status = order_result["response"]["data"]["statuses"][0]
        if "resting" in status:
            order_status = info.query_order_by_oid(address, status["resting"]["oid"])
            print("Order status by oid:", order_status)

    # Cancel the order
    if order_result["status"] == "ok":
        status = order_result["response"]["data"]["statuses"][0]
        if "resting" in status:
            cancel_result = exchange.cancel("ETH", status["resting"]["oid"])
            print(cancel_result)


if __name__ == "__main__":
    main()

Step-by-Step Explanation

  1. Setup: The example_utils.setup() function initializes the Info and Exchange clients using credentials from your config.json.
  2. Fetch User State: We use info.user_state(address) to get a snapshot of the account's current positions. This is useful for context before placing new trades.
  3. Place a Limit Order:
    • The exchange.order(...) method is called to send a new order.
    • "ETH": The asset to trade.
    • True: This is a buy order (is_buy=True).
    • 0.2: The size of the order.
    • 1100: The limit price. We set this far from the market to ensure it becomes a resting order.
    • {"limit": {"tif": "Gtc"}}: This specifies a limit order with a Time-in-Force of "Good 'til Canceled".
  4. Parse the Response: The API returns a JSON response. If the status is "ok", we parse the response to find the status of our order. If it's a resting order, the status will contain a "resting" object with the unique oid (Order ID).
  5. Query by OID: We use info.query_order_by_oid(address, oid) to fetch the details of our newly placed order from the exchange, confirming its status.
  6. Cancel the Order: Finally, we use exchange.cancel("ETH", oid) to cancel the resting order using its OID.