> For the complete documentation index, see [llms.txt](https://docs.dmex.app/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.dmex.app/api-docs/websocket/create-order.md).

# Create Order

## Create Order API

This guide explains how to programmatically create orders on the DMEX exchange.

### Overview

Orders are created by:

1. Building the order parameters
2. Generating a keccak256 hash of the order
3. Signing the hash with your private key
4. Sending the signed order via WebSocket

### Order Parameters

| Parameter       | Type    | Description                                       |
| --------------- | ------- | ------------------------------------------------- |
| `amount`        | string  | Order size (will be multiplied by 1e8)            |
| `price`         | string  | Order price (will be multiplied by 1e8)           |
| `side`          | boolean | `true` = buy/long, `false` = sell/short           |
| `leverage`      | string  | Leverage multiplier (e.g., "10" for 10x)          |
| `base_token`    | address | The margin token contract address                 |
| `asset`         | string  | Trading pair symbol (e.g., "BTC", "ETH")          |
| `closing_order` | boolean | `true` if this order closes an existing position  |
| `stop`          | boolean | `true` if this is a stop order                    |
| `stop_price`    | string  | Trigger price for stop orders (multiplied by 1e8) |
| `is_market`     | boolean | `true` for market orders                          |
| `post_only`     | boolean | `true` to ensure order is maker only              |
| `replace_hash`  | string  | Hash of order to replace, or zero hash            |

### JavaScript/TypeScript Example

```typescript
import { ethers } from 'ethers';
import Web3 from 'web3';

// Configuration
const WS_ENDPOINT = 'wss://api.dmex.app/ws';
const BASE_TOKEN = '0x...'; // USDC or other margin token address

async function createOrder({
    privateKey,
    asset,
    amount,
    price,
    side,
    leverage,
    closingOrder = false,
    stop = false,
    stopPrice = '0',
    isMarket = false,
    postOnly = false,
    replaceHash = ''
}: {
    privateKey: string;
    asset: string;
    amount: string;
    price: string;
    side: boolean;
    leverage: string;
    closingOrder?: boolean;
    stop?: boolean;
    stopPrice?: string;
    isMarket?: boolean;
    postOnly?: boolean;
    replaceHash?: string;
}) {
    // Initialize web3 for signing
    const web3 = new Web3();
    const account = web3.eth.accounts.privateKeyToAccount(privateKey);
    const userAddress = account.address;

    // Convert to 1e8 precision
    const amountScaled = (Number(amount) * 1e8).toFixed(0);
    const priceScaled = (Number(price) * 1e8).toFixed(0);
    const stopPriceScaled = (Number(stopPrice) * 1e8).toFixed(0);

    // Generate unique nonce
    const nonce = Date.now();

    // Create order hash
    const orderHash = ethers.utils.keccak256(
        ethers.utils.defaultAbiCoder.encode(
            ['string', 'address', 'address', 'uint256', 'uint256', 'bool', 'uint256', 'uint256'],
            [asset, BASE_TOKEN, userAddress, amountScaled, priceScaled, side, nonce, leverage]
        )
    );

    // Sign the hash
    const signedData = web3.eth.accounts.sign(orderHash, privateKey);
    const signature = signedData.signature;

    // Parse signature into v, r, s
    const sig = signature.slice(2);
    const r = `0x${sig.slice(0, 64)}`;
    const s = `0x${sig.slice(64, 128)}`;
    let v = parseInt(`0x${sig.slice(128, 130)}`, 16);
    if (v < 27) v += 27;

    // Format replace_hash
    const formattedReplaceHash = replaceHash === '' 
        ? '0x0000000000000000000000000000000000000000000000000000000000000000'
        : replaceHash;

    // Build order payload
    const order = {
        hash: orderHash,
        user_address: userAddress,
        base_token: BASE_TOKEN,
        asset: asset,
        amount: amountScaled,
        price: priceScaled,
        side: side,
        nonce: nonce,
        leverage: leverage,
        closing_order: closingOrder,
        v: v,
        r: r,
        s: s,
        remaining_amount: amountScaled,
        closed: false,
        stop: stop,
        stop_price: stopPriceScaled,
        stopped: false,
        is_market: isMarket,
        replace_hash: formattedReplaceHash,
        post_only: postOnly
    };

    return order;
}

// Send order via WebSocket
function sendOrder(ws: WebSocket, order: object) {
    const message = JSON.stringify({
        op: 'create_order',
        data: order
    });
    ws.send(message);
}

// Usage Example
async function main() {
    const privateKey = '0x...'; // Your private key
    
    // Create a limit buy order for 0.1 BTC at $50,000 with 10x leverage
    const order = await createOrder({
        privateKey,
        asset: 'BTC',
        amount: '0.1',
        price: '50000',
        side: true,        // true = buy/long
        leverage: '10',
        closingOrder: false,
        isMarket: false,
        postOnly: false
    });

    // Connect to WebSocket and send
    const ws = new WebSocket(WS_ENDPOINT);
    
    ws.onopen = () => {
        console.log('Connected');
        sendOrder(ws, order);
    };

    ws.onmessage = (event) => {
        const response = JSON.parse(event.data);
        console.log('Response:', response);
    };
}
```

### Python Example

```python
import json
import time
import websocket
from web3 import Web3
from eth_abi import encode

# Configuration
WS_ENDPOINT = 'wss://api.dmex.app/ws'
BASE_TOKEN = '0x...'  # USDC or other margin token address

def create_order(
    private_key: str,
    asset: str,
    amount: str,
    price: str,
    side: bool,
    leverage: str,
    closing_order: bool = False,
    stop: bool = False,
    stop_price: str = '0',
    is_market: bool = False,
    post_only: bool = False,
    replace_hash: str = ''
):
    w3 = Web3()
    account = w3.eth.account.from_key(private_key)
    user_address = account.address

    # Convert to 1e8 precision
    amount_scaled = str(int(float(amount) * 1e8))
    price_scaled = str(int(float(price) * 1e8))
    stop_price_scaled = str(int(float(stop_price) * 1e8))

    # Generate unique nonce
    nonce = int(time.time() * 1000)

    # Create order hash
    encoded = encode(
        ['string', 'address', 'address', 'uint256', 'uint256', 'bool', 'uint256', 'uint256'],
        [asset, BASE_TOKEN, user_address, int(amount_scaled), int(price_scaled), side, nonce, int(leverage)]
    )
    order_hash = Web3.keccak(encoded).hex()

    # Sign the hash
    signed = w3.eth.account.sign_message(
        encode_defunct(hexstr=order_hash),
        private_key=private_key
    )
    
    v = signed.v
    r = hex(signed.r)
    s = hex(signed.s)

    # Format replace_hash
    formatted_replace_hash = (
        '0x0000000000000000000000000000000000000000000000000000000000000000'
        if replace_hash == '' else replace_hash
    )

    # Build order payload
    order = {
        'hash': order_hash,
        'user_address': user_address,
        'base_token': BASE_TOKEN,
        'asset': asset,
        'amount': amount_scaled,
        'price': price_scaled,
        'side': side,
        'nonce': nonce,
        'leverage': leverage,
        'closing_order': closing_order,
        'v': v,
        'r': r,
        's': s,
        'remaining_amount': amount_scaled,
        'closed': False,
        'stop': stop,
        'stop_price': stop_price_scaled,
        'stopped': False,
        'is_market': is_market,
        'replace_hash': formatted_replace_hash,
        'post_only': post_only
    }

    return order


def send_order(ws, order):
    message = json.dumps({
        'op': 'create_order',
        'data': order
    })
    ws.send(message)


# Usage Example
if __name__ == '__main__':
    from eth_account.messages import encode_defunct
    
    private_key = '0x...'  # Your private key
    
    # Create a limit buy order for 0.1 BTC at $50,000 with 10x leverage
    order = create_order(
        private_key=private_key,
        asset='BTC',
        amount='0.1',
        price='50000',
        side=True,  # True = buy/long
        leverage='10',
        closing_order=False,
        is_market=False,
        post_only=False
    )

    # Connect and send
    ws = websocket.create_connection(WS_ENDPOINT)
    send_order(ws, order)
    
    response = ws.recv()
    print('Response:', response)
    ws.close()
```

### Order Hash Structure

The order hash is generated using `keccak256` with ABI-encoded parameters:

```
keccak256(abi.encode(
    asset,        // string  - Trading pair symbol
    base_token,   // address - Margin token contract
    user_address, // address - Your wallet address
    amount,       // uint256 - Order size * 1e8
    price,        // uint256 - Order price * 1e8
    side,         // bool    - true=buy, false=sell
    nonce,        // uint256 - Unique timestamp
    leverage      // uint256 - Leverage multiplier
))
```

### Order Types

#### Limit Order

```typescript
{
    is_market: false,
    stop: false,
    post_only: false  // or true for maker-only
}
```

#### Market Order

```typescript
{
    is_market: true,
    stop: false
}
```

#### Stop-Limit Order

```typescript
{
    is_market: false,
    stop: true,
    stop_price: '49000'  // Trigger price
}
```

#### Stop-Market Order

```typescript
{
    is_market: true,
    stop: true,
    stop_price: '49000'
}
```

### Closing Positions

To close an existing position, set `closing_order: true`. The `side` should be opposite to your current position:

* To close a long position: `side: false` (sell)
* To close a short position: `side: true` (buy)

### Replacing Orders

To replace an existing order, pass the hash of the order you want to cancel in `replace_hash`. This atomically cancels the old order and creates the new one.

### Error Handling

Common validation errors:

* **Amount must be greater than zero**
* **Invalid signature** - Ensure the hash is signed correctly
* **Insufficient margin** - Not enough balance for the order
* **Invalid leverage** - Leverage outside allowed range for the asset

### WebSocket Response

Successful order creation returns:

```json
{
    "op": "order_created",
    "data": {
        "hash": "0x...",
        "status": "open"
    }
}
```
