Trades
The Trade endpoint returns the fill history for an account — every executed order that resulted in a position change. Use this to analyze your strategy’s trading activity, calculate performance metrics, or build a trade journal.
Trades vs. Orders
- Orders are instructions to buy or sell (may be pending, partially filled, filled, or canceled)
- Trades (also called “fills”) are the actual executions — completed transactions where contracts changed hands
An order with status 2 (Filled) will have a corresponding trade. Pending and canceled orders do not generate trades.
POST Trade/search
Get the trade/fill history for an account. Returns all trades executed during the current session.
URL: POST /api/topstep-sim/Trade/search
Authentication: Bearer token required.
Request body
{ "accountId": 12345}| Field | Type | Required | Description |
|---|---|---|---|
accountId | number | Yes | Account ID |
Response
{ "success": true, "errorCode": 0, "errorMessage": null, "trades": [ { "id": "trd_xyz789", "orderId": "ord_abc123", "accountId": 12345, "contractId": "CON.F.US.ENQ.H25", "side": 0, "size": 1, "price": 21503.25, "timestamp": "2025-01-15T14:30:05Z" }, { "id": "trd_xyz790", "orderId": "ord_def456", "accountId": 12345, "contractId": "CON.F.US.ENQ.H25", "side": 1, "size": 1, "price": 21518.50, "timestamp": "2025-01-15T14:45:12Z" } ]}| Field | Type | Description |
|---|---|---|
trades | array | List of trade/fill objects, ordered chronologically |
trades[].id | string | Unique trade identifier |
trades[].orderId | string | The order ID that generated this trade |
trades[].accountId | number | Account ID |
trades[].contractId | string | Contract ID |
trades[].side | number | 0 = Buy, 1 = Sell |
trades[].size | number | Number of contracts filled |
trades[].price | number | Execution price |
trades[].timestamp | string | ISO 8601 timestamp of the fill |
Example
result = api("Trade/search", {"accountId": ACCOUNT_ID})
if result["success"]: trades = result.get("trades", []) print(f"Total trades: {len(trades)}")
for trade in trades: side = "BUY" if trade["side"] == 0 else "SELL" print(f" {trade['timestamp']} — {side} {trade['size']} @ {trade['price']}")curl -X POST https://api.test-max.com/api/topstep-sim/Trade/search \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{"accountId": 12345}'Calculating performance from trades
You can compute key performance metrics directly from the trade history:
Total P&L
result = api("Trade/search", {"accountId": ACCOUNT_ID})trades = result.get("trades", [])
# Pair up buy/sell trades to calculate round-trip P&Ltotal_pnl = 0.0buys = []
for trade in trades: if trade["side"] == 0: # Buy buys.append(trade) elif trade["side"] == 1 and buys: # Sell (close) entry = buys.pop(0) pnl = (trade["price"] - entry["price"]) * trade["size"] * TICK_VALUE / TICK_SIZE total_pnl += pnl
print(f"Total P&L: ${total_pnl:,.2f}")Win rate
wins = 0losses = 0round_trips = []
# Pair trades into round tripsfor i in range(0, len(trades) - 1, 2): entry = trades[i] exit_trade = trades[i + 1]
if entry["side"] == 0: # Long trade pnl = exit_trade["price"] - entry["price"] else: # Short trade pnl = entry["price"] - exit_trade["price"]
if pnl > 0: wins += 1 elif pnl < 0: losses += 1
round_trips.append(pnl)
total_trades = wins + losseswin_rate = (wins / total_trades * 100) if total_trades > 0 else 0print(f"Win rate: {win_rate:.1f}% ({wins}W / {losses}L)")Trade count and frequency
from datetime import datetime
trades = result.get("trades", [])if len(trades) >= 2: first = datetime.fromisoformat(trades[0]["timestamp"].replace("Z", "+00:00")) last = datetime.fromisoformat(trades[-1]["timestamp"].replace("Z", "+00:00")) duration = last - first print(f"Session duration: {duration}") print(f"Trades: {len(trades)} over {duration}")Usage notes
- Trades are returned in chronological order (oldest first).
- Each fill is a separate trade object, even if the order was partially filled across multiple prices.
- The trade list is scoped to the current replay session. Starting a new session resets the trade history.
- Use
Trade/searchafter callingReplay/endto get the complete trade log for a session. The session results include an aggregate summary, whileTrade/searchgives you the individual fill details.