Bash / Shell NinjaTrader 8 API examples
Shell scripts that drive NinjaTrader 8 through CrossTrade. Pipeline-friendly: pull orders, filter with jq, batch-cancel.
/v1/api/accounts/{account}/orders/{orderId} CancelOrder Cancel a working order by ID.
Open in the CancelOrder docs →Using Bash / Shell against the CrossTrade NinjaTrader API
For ops, monitoring, and ad-hoc scripts, bash + curl + jq is the fastest path. Pull orders, filter for stale ones, and cancel them in a one-liner pipeline. WebSocket use case is observational (live tail with websocat).
curl + jq websocat (cargo install websocat) or wscat Watch the request get written
A pseudo-developer types out a real DELETE CancelOrder call against your NinjaTrader 8 account. The animation runs on a loop; the static snippet below is yours to copy.
Complete Bash / Shell CancelOrder example
#!/bin/bash
# Cancel every working order older than 1 hour
TOKEN="your-bearer-token"
ACCOUNT="Sim101"
BASE="https://app.crosstrade.io/v1/api"
curl -s "$BASE/accounts/$ACCOUNT/orders" -H "Authorization: Bearer $TOKEN" \
| jq -r --argjson cut $(date -d "1 hour ago" +%s) \
'.orders[] | select(.timestamp < $cut) | .orderId' \
| while read OID; do
echo "Cancelling $OID"
curl -s -X DELETE "$BASE/accounts/$ACCOUNT/orders/$OID" \
-H "Authorization: Bearer $TOKEN"
done Streaming data with websocat (cargo install websocat) or wscat
Same flow on a persistent connection: open the socket, send a subscribe message, receive market data or P&L pushes in real time. CrossTrade's WebSocket is at wss://app.crosstrade.io/ws/stream with the same Bearer token in the request header.
Complete Bash / Shell WebSocket example
#!/bin/bash
# Live tail of market data with websocat + jq
TOKEN="your-bearer-token"
websocat "wss://app.crosstrade.io/ws/stream" \
-H "Authorization: Bearer $TOKEN" \
--text \
--send-text '{"action":"subscribe","instruments":["ES 12-25"]}' \
| jq -r --unbuffered '.quotes[]? | "\(.instrument) \(.last)"' The full Bash / Shell-compatible API surface
Every endpoint documented with request/response schemas, error codes, rate-limit notes, and language-specific code samples.
Same API, different language
Common questions
Is bash a serious language for trading?
For the right scope, yes. Cron-scheduled risk reports, EOD reconciliation, batch cancel-stale-orders, CI smoke tests, and ops debugging are all natural bash + curl + jq pipelines. For stateful strategy logic, you want a real programming language — but bash + jq covers a surprising amount of trading ops glue work without dependencies.
websocat or wscat?
Both work against CrossTrade's WebSocket. websocat is a Rust binary — install with cargo install websocat or via package manager. It composes beautifully with shell pipes (the example pipes websocat into jq). wscat needs Node (npm install -g wscat) and is more interactive — better for ad-hoc exploration than scripted pipelines.
Running these scripts from cron?
Yes, with these conventions: put the script in /etc/cron.d/ or your user's crontab, source the bearer token from a 0600-mode file (never embed it in the script), set -euo pipefail at the top so failures actually fail, and log to a file you can rotate. Mail-on-failure via MAILTO= in the crontab.
Windows / PowerShell equivalent?
Yes — use Invoke-RestMethod for REST (built into PowerShell, auto-parses JSON). For WebSocket on Windows, use the .NET ClientWebSocket class directly from PowerShell, run WSL with websocat, or install a native build of websocat for Windows. Same Authorization: Bearer pattern.
Better error handling for trading scripts?
Wrap curl in a function that checks the HTTP status (curl -w "%{http_code}") and exits non-zero on 4xx/5xx. Echo the offending account / order ID into the error so the log is actionable. For production, pipe errors to a notification service (Slack webhook, Telegram bot).
When to escalate beyond bash?
If your script needs to handle concurrent inputs, hold long-lived state across runs, or do anything beyond text transforms — escalate to Python (still callable from a shell script) or Go. The break-even is usually around 100 lines of bash; past that, readability tanks.
Securing the bearer token in shell scripts?
Source it from a separate file: source ~/.crosstrade-secrets (which contains export TOKEN="..."), and chmod 600 ~/.crosstrade-secrets. Never commit the token to git, never embed it in the script itself. Use a secret manager (AWS SSM, HashiCorp Vault, age-encrypted files) for any production / shared environment.
Can I use this for a trading bot that runs 24/7?
For slow strategies (5+ minute cycles), yes — a loop of curl + sleep can drive a trading workflow cleanly. For anything tighter, use a real language with a proper event loop. The break-even is roughly: if your script needs to handle concurrent inputs or hold long-lived state, escalate beyond bash.
Fish or Zsh instead of Bash?
Either works. The examples use bash syntax for the widest compatibility (BSD-compatible #!/bin/bash works everywhere). Zsh runs bash scripts unchanged. Fish needs minor syntax tweaks (no [[ ]] tests, different function syntax) but the curl + jq pipeline core is identical.
Build your first NinjaTrader 8 trading bot in Bash / Shell
One bearer token, one URL, every NinjaTrader endpoint. Ship to Sim101 first.