POST Flatten Positions
- NT8
- Tradovate
Flatten positions by account and/or instrument NT8
Flatten allows for flattening all positions and orders in an account or for a specific instrument in an account. Differs from Flatten Everything, which flattens all positions and order in all accounts for all instruments.
Endpoint
POST /v1/api/accounts/{account}/positions/flatten
Headers
| Name | Value |
|---|---|
| Content-Type | application/json |
| Authorization | Bearer <token> |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | Required | Name of account in NT8 |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
instrument | string | Optional | If provided, only flatten positions for this instrument. |
marketPosition | string | Optional | If provided, only flatten positions matching this side: "Long" or "Short". Can be combined with instrument. |
cancelOrders | boolean | Optional | If true, explicitly cancels all remaining working orders for the account (and instrument, if specified) after the flatten call. Default: false. Recommended for sim accounts where NT8's native flatten does not reliably cancel attached stop/target orders. |
Code examples
- Python
- JavaScript
- cURL
import requests
token = 'my-secret-token'
url = "https://app.crosstrade.io/v1/api/accounts/Sim101/positions/flatten"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {}
try:
response = requests.post(url, headers=headers, json=data)
print(f"Response Code: {response.status_code}, Response Text: {response.text}")
except Exception as e:
print(f"An error occurred: {e}")
const token = 'my-secret-token';
const url = "https://app.crosstrade.io/v1/api/accounts/Sim101/positions/flatten";
fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({})
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
TOKEN="my-secret-token"
curl -X POST "https://app.crosstrade.io/v1/api/accounts/Sim101/positions/flatten" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Response
- 200
- 400
{
"success": true,
"pending": true,
"verified": false,
"closedPositions": [],
"closingPositions": [
{
"type": "NinjaTrader.Cbi.Position",
"account": "Sim101",
"instrument": "MES 12-25",
"instrumentType": "Future",
"marketPosition": "Short",
"quantity": 1,
"averagePrice": 5803.25,
"marketPrice": 5802.0,
"unrealizedProfitLoss": 6.25
}
],
"closeRequests": [
{
"success": true,
"pending": true,
"verified": false,
"disposition": "pending",
"remainingQuantity": 1,
"orderId": "9f2c1b7d43a04e0a8e2f6c5d1b3a7e40",
"account": "Sim101",
"instrument": "MES 12-25"
}
]
}
closeRequests carries one entry per position, so a multi-position flatten reports each
instrument's outcome separately.
{
"error": "Invalid request"
}
Platform nuances
A close is submitted first and confirmed second. closedPositions lists only positions the
add-on saw reach flat before it answered. Anything still working is listed in
closingPositions with pending: true and verified: false, and the response carries
remainingQuantity and the orderId of the closing order. Poll
GET Positions to confirm the final state.
Overlapping close requests for the same account and instrument join the operation already
running instead of starting a second one, so a retry cannot leave two closing orders in the
market. When a close cannot be completed safely the response carries an error code, such
as close_in_progress or close_needs_reconciliation, with a detail message, and no
further order is sent.
cancelOrders: true mattersClosing a position cancels the resting orders on that same instrument first. cancelOrders: true additionally sweeps working orders on instruments that are already flat, which is what
you want when a stop or target is left over from a position that closed earlier. If you need
a guaranteed clean exit on a single instrument, this is the correct pattern:
{
"instrument": "ES 12-26",
"cancelOrders": true
}
Flatten Everything always cancels orders explicitly and does not require this flag.
WebSocket API
This request can also be made over the WebSocket API. The account path parameter and request body fields are all passed inside args.
{
"action": "rpc",
"id": "my-request-id",
"api": "Flatten",
"args": {
"account": "Sim101",
"instrument": "ES 12-26"
}
}
Flatten positions by account and/or instrument Tradovate
Flattens positions on one linked Tradovate account, optionally filtered by instrument and side. The request executes server-side through the same validation and controls as a Tradovate webhook signal, including field validation, Account Manager locks, and Trade Copier fan-out.
Endpoint
POST /v1/api/tv/accounts/{account}/positions/flatten
Headers
| Name | Value |
|---|---|
| Content-Type | application/json |
| Authorization | Bearer <token> |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
account | string | Required | Tradovate account name, such as DEMO12345678 |
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
instrument | string | Optional | Continuous (ES1!), NT8 (ES 12-26), or Tradovate (ESZ6) instrument filter |
marketPosition | string | Optional | Position-side filter: long or short; can be combined with instrument |
An empty body flattens every position on the specified account. Tradovate does not use the NT8
cancelOrders body field on this endpoint.
Code examples
- Python
- JavaScript
- cURL
import requests
token = 'my-secret-token'
url = "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/positions/flatten"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"instrument": "ES1!"
}
try:
response = requests.post(url, headers=headers, json=data)
print(f"Response Code: {response.status_code}, Response Text: {response.text}")
except Exception as e:
print(f"An error occurred: {e}")
const token = 'my-secret-token';
const url = "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/positions/flatten";
const data = {
instrument: "ES1!"
};
fetch(url, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));
TOKEN="my-secret-token"
curl -X POST "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/positions/flatten" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"instrument": "ES1!"}'
Response
This abbreviated response envelope identifies the operation. The full response also includes
dispatcher context and the flatten results inside response.
{
"success": true,
"api": "flatten_filtered",
"response": {}
}
Platform nuances
- Tradovate uses lowercase
long/shortvalues formarketPosition, unlike NT8'sLong/Short. - Tradovate accepts three instrument naming forms.
- Account Manager and Trade Copier behavior is applied by the shared dispatcher.
- Use
POST /v1/api/tv/positions/flattento liquidate positions and cancel working orders across every linked Tradovate identity.
See the Tradovate API overview for the full field grammar, mutation safety guarantees, and error table.