> For the complete documentation index, see [llms.txt](https://docs.hydromancer.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hydromancer.xyz/readme/rest-api/user-performance/usercompletedtrades.md).

# userCompletedTrades

Returns the latest N completed trades for a user, newest-first. A completed trade represents a position that has been fully closed (size returned to \~0). Each record includes gross/net/funding PnL, average entry and exit prices, fees, fill counts (total and maker), open/close timestamps, duration, peak position size during the position's lifetime, leverage at close, and last-touch builder attribution.

`dex` is optional. Omit to return trades from every perp DEX. Set to `"main_dex"` for the native Hyperliquid dex, or to a HIP-3 dex name (e.g. `"xyz"`) to scope the trade list to that dex.

**note: data used to compute the leaderboard is starting from 1st of aug 2025**

## POST Request

<table><thead><tr><th width="161.9998779296875">Field</th><th width="119">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>type</code></td><td>string</td><td>Must be <code>"userCompletedTrades"</code></td></tr><tr><td><code>user</code></td><td>string</td><td>Ethereum address (0x-prefixed, 42 characters)</td></tr><tr><td><code>builder</code></td><td>string</td><td>Filter to trades whose closing fill was routed through this builder address (last-touch attribution, 0x-prefixed). Omit for no filtering (optional)</td></tr><tr><td><code>limit</code></td><td>int</td><td>Max results to return. Default 100, max 500 (optional)</td></tr><tr><td><code>dex</code></td><td>string</td><td>Scope to a single perp DEX. <code>"main_dex"</code> for the native Hyperliquid dex, or a HIP-3 dex name (e.g. <code>"xyz"</code>). Omit for all dexes (optional)</td></tr></tbody></table>

{% tabs %}
{% tab title="cURL" %}

```bash
curl -X POST https://api.hydromancer.xyz/info \
  -H "Authorization: Bearer $HYDROMANCER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "userCompletedTrades",
    "user": "0x0000000000000000000000000000000000000000",
    "limit": 100
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import os

response = requests.post(
    'https://api.hydromancer.xyz/info',
    json={
        'type': 'userCompletedTrades',
        'user': '0x0000000000000000000000000000000000000000',
        'limit': 100
    },
    headers={
        'Authorization': f'Bearer {os.environ.get("HYDROMANCER_API_KEY")}',
        'Content-Type': 'application/json'
    }
)

print(response.json())
```

{% endtab %}

{% tab title="Javascript" %}

```javascript
import axios from 'axios';

try {
    const response = await axios.post('https://api.hydromancer.xyz/info', {
        type: 'userCompletedTrades',
        user: '0x0000000000000000000000000000000000000000',
        limit: 100
    }, {
        headers: {
            'Authorization': `Bearer ${process.env.HYDROMANCER_API_KEY}`,
            'Content-Type': 'application/json'
        }
    });

    console.log(response.data);
} catch (error) {
    console.error('Error:', error.message);
}
```

{% endtab %}
{% endtabs %}

***

## Response Fields

The response is a JSON array of completed-trade records, ordered newest-first by `close_time` then `tx_index`.

| Field                  | Type     | Description                                                                                                                      |
| ---------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `user`                 | string   | Ethereum address                                                                                                                 |
| `coin`                 | string   | Asset symbol                                                                                                                     |
| `position_type`        | string   | `"Long"` or `"Short"`                                                                                                            |
| `gross_pnl`            | string   | Realized PnL before fees (`exit_value - entry_value`, sign-adjusted for shorts)                                                  |
| `net_pnl`              | string   | Realized PnL after fees and funding (`gross_pnl - fees + funding_pnl`)                                                           |
| `funding_pnl`          | string   | Cumulative funding PnL accrued while the position was open (positive = received, negative = paid). Already included in `net_pnl` |
| `entry_px`             | string   | Volume-weighted average entry price                                                                                              |
| `exit_px`              | string   | Volume-weighted average exit price                                                                                               |
| `position_closed_size` | string   | Size of the closed position, in contracts                                                                                        |
| `fees`                 | string   | Total fees paid on fills attributed to this position                                                                             |
| `fills`                | int      | Number of fills on this position                                                                                                 |
| `maker_fills`          | int      | Number of uncrossed (maker) fills on this position                                                                               |
| `open_time`            | int      | Time the position was opened (Unix ms)                                                                                           |
| `close_time`           | int      | Time the position was fully closed (Unix ms)                                                                                     |
| `duration_ms`          | int      | `close_time - open_time` in milliseconds                                                                                         |
| `max_position_size`    | string   | Peak absolute position size reached during the position's lifetime                                                               |
| `builder`              | string?  | Builder address from the closing fill, if any (last-touch attribution)                                                           |
| `tx_index`             | int      | Transaction index of the closing fill (use with `close_time` for cursor-based pagination)                                        |
| `leverage`             | int?     | Leverage multiplier at close (e.g. `10` = 10x). `null` if unknown — typically when the position predates leverage tracking       |
| `is_cross`             | boolean? | `true` = cross margin, `false` = isolated. `null` when `leverage` is null                                                        |

<details>

<summary>Response</summary>

```json
[
  {
    "user": "0x0000000000000000000000000000000000000000",
    "coin": "BTC",
    "position_type": "Long",
    "gross_pnl": "1240.50",
    "net_pnl": "1215.15",
    "funding_pnl": "-3.10",
    "entry_px": "45000.00",
    "exit_px": "45620.00",
    "position_closed_size": "2.0",
    "fees": "22.25",
    "fills": 4,
    "maker_fills": 2,
    "open_time": 1734567890123,
    "close_time": 1734571490123,
    "duration_ms": 3600000,
    "max_position_size": "2.5",
    "builder": null,
    "tx_index": 12,
    "leverage": 10,
    "is_cross": true
  }
]
```

</details>
