POST Reverse Position
- NT8
- Tradovate
Combined Close Position and Place Order NT8
Closes the current position and opens a new one with the parameters you specify. Requires action, quantity, orderType, and timeInForce. Returns an error if no position is currently open. Use this when you need explicit control over the size or order type of the replacement entry.
Endpoint
POST /v1/api/accounts/{account}/positions/reverseposition
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 | Required | Name of underlying instrument (e.g., "ES 12-24") |
action | string | Required | BUY, SELL |
quantity | int | Required | Contract quantity of new order |
orderType | string | Required | MARKET, LIMIT, STOPMARKET, STOPLIMIT |
timeInForce | string | Required | DAY, GTC |
limitPrice | float | Optional | Limit price when submitting limit order type |
stopPrice | float | Optional | Stop price when submitting stop order type |
ocoId | string | Optional | Create or append to OCO order by ID |
strategy | string | Optional | ATM strategy name if opening with ATM template |
Code examples
- Python
- JavaScript
- cURL
import requests
token = 'my-secret-token'
url = "https://app.crosstrade.io/v1/api/accounts/Sim101/positions/reverseposition"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"instrument": "MES 12-25",
"action": "BUY",
"orderType": "MARKET",
"quantity": 1,
"timeInForce": "DAY"
# "limitPrice": 5500
# "stopPrice": 0,
# "ocoId": "abc123",
# "strategy": "MyAtmStrategy"
}
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/reverseposition";
const data = {
instrument: "MES 12-25",
action: "BUY",
orderType: "MARKET",
quantity: 1,
timeInForce: "DAY"
// limitPrice: 5500,
// stopPrice: 0,
// ocoId: "abc123",
// strategy: "MyAtmStrategy"
};
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/accounts/Sim101/positions/reverseposition" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"instrument": "MES 12-25",
"action": "BUY",
"orderType": "MARKET",
"quantity": 1,
"timeInForce": "DAY"
}'
Response
- 200
- 400
{
"orderId": "cb1fc8d4e1a84d29ae38fea964aaac8c",
"success": true
}
{
"error": "No position found for instrument 'ES 12-25' in account 'sim101'"
}
Platform nuances
Flatten-wait behavior — Before placing the new entry order, this endpoint waits for the existing position to fully close and all associated orders to clear (up to ~5 seconds). This prevents the double-position problem that occurs when an entry fills before the close has processed. Under normal live conditions this wait is near-instant. In sim or during high broker latency, the full wait may be observed. If settlement times out, the operation fails closed and does not place the replacement entry.
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": "ReversePosition",
"args": {
"account": "Sim101",
"instrument": "ES 09-26",
"action": "Buy",
"orderType": "Market",
"quantity": 1,
"timeInForce": "Gtc"
}
}
Combined Close Position and Place Order Tradovate
Flattens the current Tradovate position, then places an explicitly sized replacement entry in the requested direction. The request executes server-side through the shared webhook parser and dispatcher, including field validation, Account Manager locks, and Trade Copier fan-out.
Endpoint
POST /v1/api/tv/accounts/{account}/positions/reverseposition
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 | Required | Continuous (ES1!), NT8 (ES 09-26), or Tradovate (ESU6) instrument form |
action | string | Required | Replacement entry side: buy or sell |
qty | int | Required | Contract quantity for the replacement entry |
orderType | string | Required | market, limit, stop, stoplimit, mit, trailingstop, or trailingstoplimit |
limitPrice | float | Optional | Limit price for order types that require one |
stopPrice | float | Optional | Stop trigger price for order types that require one |
tif | string | Optional | Time in force |
takeProfit | number | Optional | Absolute price for a Tradovate-native OCO target leg |
stopLoss | number | Optional | Absolute price for a Tradovate-native OCO stop leg |
orderId | string | Optional | Caller-supplied order reference |
text | string | Optional | Free-form Tradovate order note |
expireTime | string | Optional | ISO-8601 expiry; required when tif=gtd |
maxShow | int | Optional | Native iceberg display quantity |
trailOffset | number | Optional | Native trailing-stop distance; required for trailing order types |
pegDifference | number | Optional | Alias of trailOffset |
requireMarketPosition | string | Optional | Gate the operation on flat, long, or short |
maxPositions | int | Optional | Block the new entry when this many positions are already open |
cancelAfter | int | Optional | Cancel an unfilled limit entry after 1 to 180 minutes |
syncStrategy | bool | Optional | Enable Tradovate Strategy Sync for this entry command |
marketPosition | string | Optional | Remote strategy target side: flat, long, or short |
prevMarketPosition | string | Optional | Remote strategy side before this signal |
outOfSync | string | Optional | Mismatch policy: wait, flatten, ignore, or resync |
targetQuantity | int | Optional | Exact signed target quantity for resync mode |
strategyExitBlock | bool | Optional | Reject non-opening strategy transitions |
atmTargets | string | Optional | Inline ATM profit-target tiers in ticks or points |
atmStops | string | Optional | Inline ATM stop tiers in ticks or points |
atmQtys | string | Optional | Contract quantities for the inline ATM tiers |
atmTrail | string | Optional | Per-tier trailing-stop toggles |
atmTrailTrigger | string | Optional | Profit distance that activates trailing tiers. Set with atmTrailOffset |
atmTrailOffset | string | Optional | Distance the activated stop follows behind price. Set with atmTrailTrigger |
atmBreakeven | int | Optional | Target tier whose fill moves remaining stops to breakeven |
atmBreakevenOffset | string | Optional | Breakeven offset for the inline ATM bracket |
Targets, stops, scale-out quantities, and triggerless continuous trails are Tradovate native. Triggered trail activation, restart-safe trigger memory, and target-fill breakeven are CrossTrade-exclusive beta features. Triggered trails use CrossTrade's own live pricing rather than Tradovate entitlement data; breakeven is driven by broker fill state. Managed fields require a Day entry.
Code examples
- Python
- JavaScript
- cURL
import requests
token = 'my-secret-token'
url = "https://app.crosstrade.io/v1/api/tv/accounts/DEMO12345678/positions/reverseposition"
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
data = {
"instrument": "ES1!",
"action": "buy",
"qty": 1,
"orderType": "market"
}
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/reverseposition";
const data = {
instrument: "ES1!",
action: "buy",
qty: 1,
orderType: "market"
};
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/reverseposition" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"instrument": "ES1!", "action": "buy", "qty": 1, "orderType": "market"}'
Response
This abbreviated response envelope shows the operation result. The full response also includes dispatcher context such as destination, account, instrument, and duration.
{
"success": true,
"api": "reverse",
"response": {}
}
Platform nuances
- Tradovate body fields use the same camelCase keys as the NT8 surface; enum values stay lowercase (
buy,market), unlike NT8'sBUY/MARKET. - The existing position is flattened before the specified replacement entry is placed.
- If settlement times out, the operation fails closed and does not place the replacement entry.
- Tradovate accepts three instrument naming forms.
- Account Manager and Trade Copier behavior is applied by the shared dispatcher.
See the Tradovate API overview for the full field grammar, mutation safety guarantees, and error table.