Skip to content

Trading

Interacting with the dYdX perpetual markets and managing your positions is done by placing orders. Enter LONG positions by placing buy orders and SHORT positions by placing sell orders.

Place an order

To place an order, you'll need your wallet ready to sign transactions. Please check the Wallet Setup guide to check how to set up a wallet. In this guide we'll be creating a short-term buy order for the ETH-USD market.

Get market parameters

To create an order for a specific market (identified by its ticker, or CLOB pair ID), we should first fetch the market parameters that allows us to do data conversions associated with that specific market. Other parameters such as the current price can also be fetched this way.

Python
MARKET_ID = 1 # ETH-USD identifier
# Fetch market parameters.
market = Market(
    (await indexer.markets.get_perpetual_markets(MARKET_ID))["markets"][MARKET_ID]
)
# Current price.
print(market["oraclePrice"])

Creating an order

Identifying the order

Every order created has an unique identifier, referred to as the order ID. It can be calculated locally and is composed of,

  • Subaccount ID: The account address plus the integer identifying the subaccount;
  • Client ID: A 32-bit integer chosen by the user to identify the order. Two orders can't have the same client ID;
  • Order flags: An integer identifying if the order is short-term (0), long-term (64), or conditional (32);
  • CLOB Pair ID: The ID of the underlying market/perpetual.
Python
order_id = market.order_id(
    ADDRESS, # address
    0, # subaccount number
    random.randint(0, 100000000), # chosen client ID, can be random
    OrderFlags.SHORT_TERM # short-term order
)

Building the order

In dYdX, orders can be either short-term or long-term, see a comparison here. A wide range of order types and parameters are provided to allow for different types of trading strategies.

  • Type: Market, Limit, and Stop, and Take Profit orders are supported;
  • Side: Purchase (BUY) or sell (SELL);
  • Size: A decimal value corresponding to the quantity being traded;
  • Price: A decimal value corresponding to the chosen price;
  • Time in Force: Execution option, defining conditions for order placements;
  • Reduce Only: A boolean value, used to label orders that can only reduce your position size. For example, a 1.25 BTC Sell Reduce Only order on a 1 BTC long:
    • If true: can only decrease your position size by 1. The remaining .25 BTC sell will not fill and be cancelled;
    • Else: The remaining .25 BTC sell can fill and the position become .25 BTC short.
  • Good until Block: Validity of the order. It is an integer value, different for short-term and long-term orders:
    • Short-term: Short term orders have a maximum validity of current block height + ShortBlockWindow. Currently, ShortBlockWindow is 20 blocks, or about 30 seconds;
    • Long-term: Stateful orders have a maximum validity of current block time + StatefulOrderTimeWindow. Currently, StatefulOrderTimeWindow this value is 95 days.
Python
# Order valid for the next 10 blocks.
good_til_block = await node.latest_block_height() + 10
# Create the order.
order = market.order(
    order_id,
    OrderType.LIMIT,
    Order.Side.SIDE_BUY,
    size=0.01, # ETH
    price=1000, # USDC
    time_in_force=Order.TimeInForce.TIME_IN_FORCE_UNSPECIFIED,
    reduce_only=False,
    good_til_block=good_til_block, # valid until this (future) block
)

Broadcasting an order

With the order now built, we can push it to the dYdX network.

Python
# Broadcast the order.
place = await node.place_order(wallet, order)

Cancel an order

An unfilled order can be cancelled. The order ID is required to cancel an order.

Python
cancel_tx = await node.cancel_order(
    wallet, order_id, good_til_block
)