Files
ritmex-bot/docs/nado/developer-resources/api/gateway/executes/place-order.md
T

10 KiB
Raw Blame History

Place Order

Rate limits

  • With spot leverage: 600 orders/minute or 10 orders/sec per wallet. (weight=1)
  • Without spot leverage: 30 orders/min or 5 orders every 10 seconds per wallet. (weight = 20)

{% hint style="info" %} See more details in API Rate limits. {% endhint %}

Request

{% tabs %} {% tab title="Websocket" %} Connect

WEBSOCKET [GATEWAY_WEBSOCKET_ENDPOINT]

Message


{
  "place_order": {
    "product_id": 1,
    "order": {
      "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
      "priceX18": "1000000000000000000",
      "amount": "1000000000000000000",
      "expiration": "4294967295",
      "nonce": "1757062078359666688",
      "appendix": "1"
    },
    "signature": "0x",
    "id": 100
  }
}

{% endtab %}

{% tab title="REST" %} POST [GATEWAY_REST_ENDPOINT]/execute

Body


{
  "place_order": {
    "product_id": 1,
    "order": {
      "sender": "0x7a5ec2748e9065794491a8d29dcf3f9edb8d7c43746573743000000000000000",
      "priceX18": "1000000000000000000",
      "amount": "1000000000000000000",
      "expiration": "4294967295",
      "nonce": "1757062078359666688"
    },
    "signature": "0x",
    "id": 100
  }
}

{% endtab %} {% endtabs %}

Request Parameters

ParameterTypeRequiredDescription
product_idnumberYesId of spot / perp product for which to place order. Use All products query to retrieve all valid product ids.
orderobjectYesOrder object, see Signing section for details on each order field.
order.senderstringYesHex string representing the subaccount's 32 bytes (address + subaccount name) of the tx sender.
order.priceX18stringYesPrice of the order multiplied by 1e18.
order.amountstringYesQuantity of the order multiplied by 1e18.
order.expirationstringYesA time after which the order should automatically be cancelled, as a timestamp in seconds after the unix epoch.
order.noncestringYesUsed to differentiate between the same order multiple times. See Signing section for more details.
order.appendixstringYesEncodes various order properties including execution types, isolated positions, TWAP parameters, and trigger types. See order appendix section for more details.
signaturestringYesHex string representing hash of the signed order. See Signing section for more details.
digeststringNoHex string representing a hash of the order.
spot_leveragebooleanNoIndicates whether leverage should be used; when set to false , placing the order fails if the transaction causes a borrow on the subaccount. Defaults to true.
idnumberNoAn optional id that when provided is returned as part of Fill and OrderUpdate stream events. See subscriptions for more details.

NOTE: The client id should not be used to differentiate orders, as it is not included in the order hash (i.e., the order digest). Instead, use the last 20 bits of the order nonce to distinguish between similar orders. For more details, refer to Order Nonce.

Signing

{% hint style="info" %} See more details and examples in our signing page. {% endhint %}

The solidity typed data struct that needs to be signed is:

struct Order {
    bytes32 sender;
    int128 priceX18;
    int128 amount;
    uint64 expiration;
    uint64 nonce;
    uint128 appendix;
}

sender: a bytes32 sent as a hex string; includes the address and the subaccount identifier

priceX18: an int128 representing the price of the order multiplied by 1e18, sent as a string. For example, a price of 1 USDT0 would be sent as "1000000000000000000"

amount: an int128 representing the quantity of the order multiplied by 1e18, sent as a string. A positive amount means that this is a buy order, and a negative amount means this is a sell order.

expiration: a time after which the order should automatically be cancelled, as a timestamp in seconds after the unix epoch, sent as a string.

Order Nonce

nonce: used to differentiate between the same order multiple times, and a user trying to place an order with the same parameters twice. Sent as a string. Encodes two bit of information:

  • Most significant 44 bits encoding the time in milliseconds (a recv_time) after which the order should be ignored by the matching engine

  • Least significant 20 bits are a random integer used to avoid hash collisions

    For example, to place an order with a random integer of 1000, and a discard time 50 ms from now, we would send a nonce of ((timestamp_ms() + 50) << 20) + 1000)

import time
unix_epoch_ms = int(time.time()) * 1000
nonce = ((unix_epoch_ms + 50) << 20) + 1000

{% hint style="warning" %} Note: for signing you should always use the data type specified in the solidity struct which might be different from the type sent in the request e.g: nonce should be an uint64 for Signing but should be sent as a string in the final payload. {% endhint %}

Order Appendix

{% hint style="info" %} See more details and examples in our Order Appendix page. {% endhint %}

appendix: is a 128-bit integer that encodes extra order parameters like execution type, isolated margin, and trigger type.

Bit Layout

| value   | reserved | trigger | reduce only | order type | isolated | version |
| 64 bits | 50 bits  | 2 bits  | 1 bit       | 2 bits     | 1 bit    | 8 bits  |
| 127..64 | 63..14   | 13..12  | 11          | 10..9      | 8        | 7..0    |

Fields (from LSB to MSB):

  • Version (8 bits, 07) protocol version (currently 1)
  • Isolated (1 bit, 8) whether the order uses isolated margin
  • Order Type (2 bits, 910) 0 = DEFAULT, 1 = IOC, 2 = FOK, 3 = POST_ONLY
    • 0 - DEFAULT: Standard limit order behavior
    • 1 - IOC (Immediate or Cancel): Execute immediately, cancel unfilled portion
    • 2 - FOK (Fill or Kill): Execute completely or cancel entire order
    • 3 - POST_ONLY: Only add liquidity, reject if would take liquidity
  • Reduce Only (1 bit, 11) only decreases an existing position.
  • Trigger Type (2 bits, 1213) 0 = NONE, 1 = PRICE, 2 = TWAP, 3 = TWAP_CUSTOM_AMOUNTS
  • Reserved (50 bits, 1463) future use
  • Value (64 bits, 64127) extra data (isolated margin or TWAP parameters)
    • if trigger is 2 or 3value represents how many times the TWAP order will execute and the maximum acceptable slippage. Encoded as:

      | times  | slippage_x6 |
      | 32 bits|   32 bits   |
      
      • times : Number of TWAP executions.
      • slippage_x6: Maximum slippage × 1,000,000 (6 decimal precision).
    • if isolated is 1value represents margin_x6 (in x6 precision, 6 decimals) to be transferred to the isolated subaccount when the order gets its first match.

    • otherwise, value is 0.

Response

Success

{
  "status": "success",
  "signature": {signature},
  "data": { 
    "digest": {order digest} 
  },
  "request_type": "execute_place_order"
  "id": 100
}

Failure

{
  "status": "failure",
  "signature": {signature},
  "error": "{error_msg}",
  "error_code": {error_code},
  "request_type": "execute_place_order"
}