-
-
Notifications
You must be signed in to change notification settings - Fork 15
Description
Summary
client.search_trades() hits GET /trades/search which returns 404 (Resource not found). TopstepX moved this endpoint to POST /Trade/search — same response format, different path and HTTP method.
Current behavior
This fails with: ProjectXDataError: Resource not found: /trades/search
trades = await client.search_trades(start_date=start, end_date=end, limit=100)
Working endpoint
POST /Trade/search works and returns the same data
payload = {
"accountId": client.account_info.id,
"startDate": start_date.isoformat(),
"endDate": end_date.isoformat(),
}
resp = await client._make_request("POST", "/Trade/search", data=payload)
resp = {"trades": [...], "success": true, "errorCode": 0, "errorMessage": null}
Response format
Each trade in resp["trades"] matches the existing Trade model:
{
"id": 2190247222,
"accountId": 19330536,
"contractId": "CON.F.US.MNQ.H26",
"creationTimestamp": "2026-02-26T14:30:05.16776+00:00",
"price": 25330.75,
"profitAndLoss": -5.5,
"fees": 0.37,
"side": 0,
"size": 1,
"voided": false,
"orderId": 2531040395
}
Suggested fix
In src/project_x_py/client/trading.py, change search_trades():
-
response = await self._make_request("GET", "/trades/search", params=params)
-
payload = { -
"accountId": account_id, -
"startDate": start_date.isoformat(), -
"endDate": end_date.isoformat(), -
} -
if contract_id: -
payload["contractId"] = contract_id -
response = await self._make_request("POST", "/Trade/search", data=payload)
-
if not response or not isinstance(response, list):
-
if not response or not isinstance(response, dict) or not response.get("success", False): return []
-
return [Trade(**trade) for trade in response]
-
return [Trade(**trade) for trade in response.get("trades", [])[:limit]]
Also noted
The docs reference get_orders(), get_recent_orders(), and position_history but none of these exist in the SDK (v3.5.9).