Go NinjaTrader 8 API examples
High-performance NinjaTrader 8 trading bots in Go. net/http for REST, gorilla/websocket for streaming with native goroutine concurrency.
Using Go against the CrossTrade NinjaTrader API
Go is the right choice when you need concurrency, low latency, and zero-dependency deployment. CrossTrade's REST API works with the stdlib net/http. For WebSocket, gorilla/websocket is the established library and handles reconnect cleanly.
net/http (stdlib) github.com/gorilla/websocket Watch the request get written
A pseudo-developer types out a real GET GetOrders call against your NinjaTrader 8 account. The animation runs on a loop; the static snippet below is yours to copy.
Complete Go GetOrders example
package main
import (
"encoding/json"
"fmt"
"net/http"
)
func main() {
req, _ := http.NewRequest("GET",
"https://app.crosstrade.io/v1/api/accounts/Sim101/orders", nil)
req.Header.Set("Authorization", "Bearer YOUR_TOKEN")
res, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
var body struct {
Orders []map[string]any `json:"orders"`
Success bool `json:"success"`
}
json.NewDecoder(res.Body).Decode(&body)
fmt.Printf("%d orders\n", len(body.Orders))
} Streaming data with github.com/gorilla/websocket
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 Go WebSocket example
package main
import (
"log"
"net/http"
"time"
"github.com/gorilla/websocket"
)
func main() {
headers := http.Header{}
headers.Set("Authorization", "Bearer YOUR_TOKEN")
for {
ws, _, err := websocket.DefaultDialer.Dial(
"wss://app.crosstrade.io/ws/stream", headers)
if err != nil {
log.Println("dial:", err, "— retrying in 5s")
time.Sleep(5 * time.Second)
continue
}
ws.WriteJSON(map[string]any{
"action": "subscribe",
"instruments": []string{"ES 12-25"},
})
for {
var msg map[string]any
if err := ws.ReadJSON(&msg); err != nil {
log.Println("read:", err)
break
}
log.Println(msg)
}
ws.Close()
time.Sleep(time.Second)
}
} The full Go-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 Go a good language for algo trading bots?
Yes. Go shines when you need predictable latency, easy concurrency (one goroutine per instrument), and zero-dependency single-binary deployment. CrossTrade's WebSocket + REST API maps cleanly onto Go's net/http and gorilla/websocket patterns.
Which WebSocket library: gorilla/websocket or nhooyr.io/websocket?
Both work great. gorilla/websocket is the longest-running standard with the largest ecosystem (the example uses it). nhooyr.io/websocket is more modern (context-first API, automatic compression). Pick based on your team's familiarity — CrossTrade is agnostic.
How do I handle the "one WebSocket per account" limit?
CrossTrade closes the older connection if a second one opens on the same account. The Go example shows a clean reconnect loop with a 5-second backoff that handles unexpected closures (server restart, network blip, session takeover). For multi-account use, open one WebSocket per account and dispatch incoming messages to per-account goroutines.
Goroutines for multiple instrument subscriptions?
Yes — but on ONE WebSocket. Send multiple subscribe messages on the same connection (instruments accumulate). Then fan out incoming marketData messages to per-instrument goroutines via a channel for processing. The one-connection-per-account limit means you don't open one socket per instrument.
How big is a compiled Go trading bot binary?
Typically 8-15MB statically linked. CGO disabled keeps it pure-Go (good for containers). Cross-compile with GOOS=linux GOARCH=amd64 for VPS deployment, or GOOS=windows for a Windows trading host.
Error-handling pattern for trading code?
Wrap every API call in a small helper that returns (T, error) and check at every step. For mcp:trade flows, never panic — always return an error and bubble up to a top-level handler that decides whether to flatten + halt or retry. Use errors.Is to distinguish rate-limit errors from auth errors.
Go vs Rust for trading: which one?
Both are excellent. Go for faster development, easier deployment, and "good enough" performance — fits 95% of trading-bot use cases. Rust when you need zero-allocation hot paths or interop with C/C++ libraries. Both produce small static binaries; Rust gives stricter memory guarantees at the cost of compile time.
Performance vs Python or Java?
Go is roughly comparable to Java and 10-50x faster than Python on CPU-bound work. For network-bound CrossTrade calls (~50ms round-trip), all three are equivalent in practice. Go wins on memory footprint and startup time, which matters for containerized deployments.
JSON-binding library?
encoding/json (stdlib) is fine for CrossTrade responses. For very high-throughput parsing, look at json-iterator/go or goccy/go-json — both drop-in faster than stdlib. Most trading code doesn't need them.
Build your first NinjaTrader 8 trading bot in Go
One bearer token, one URL, every NinjaTrader endpoint. Ship to Sim101 first.