PHP NinjaTrader 8 API examples
Server-side PHP integration with NinjaTrader 8 over CrossTrade's REST + WebSocket API. Built-in curl for REST, Ratchet/Pawl for WebSocket.
Using PHP against the CrossTrade NinjaTrader API
PHP's built-in curl extension handles REST cleanly. For WebSocket, Ratchet/Pawl is the established client. GetBars returns historical OHLC data — useful for backtesting external indicators against NT8's actual price history.
curl extension (built-in) ratchet/pawl (composer require ratchet/pawl) Watch the request get written
A pseudo-developer types out a real POST GetBars call against your NinjaTrader 8 account. The animation runs on a loop; the static snippet below is yours to copy.
Complete PHP GetBars example
<?php
$token = "your-bearer-token";
$body = json_encode([
"periodType" => "Minute",
"period" => 5,
"fromDate" => "2026-05-26T13:30:00Z",
"toDate" => "2026-05-26T20:00:00Z",
]);
$ch = curl_init("https://app.crosstrade.io/v1/api/accounts/Sim101/instruments/ES%2012-25/bars");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $token",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => true,
]);
$res = json_decode(curl_exec($ch), true);
echo count($res["bars"]) . " bars\n"; Streaming data with ratchet/pawl (composer require ratchet/pawl)
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 PHP WebSocket example
<?php
require "vendor/autoload.php";
use Ratchet\Client\Connector;
use React\EventLoop\Loop;
$connector = new Connector(Loop::get());
$connector("wss://app.crosstrade.io/ws/stream", [], [
"Authorization" => "Bearer YOUR_TOKEN",
])->then(function ($ws) {
$ws->send(json_encode([
"action" => "subscribe",
"instruments" => ["ES 12-25"],
]));
$ws->on("message", function ($msg) {
echo $msg . "\n";
});
});
Loop::run(); The full PHP-compatible API surface
Every endpoint documented with request/response schemas, error codes, rate-limit notes, and language-specific code samples.
Common questions
Is PHP a good choice for algorithmic trading?
Yes, particularly when CrossTrade is connecting to an existing PHP web stack — a Laravel admin panel, a Symfony account dashboard, a WordPress widget that shows current positions. PHP 8.x is fast (JIT), modern (typed properties, enums), and the built-in curl extension handles CrossTrade REST cleanly without any composer dependency.
Laravel integration?
Yes — use Http::withToken($token)->post(...) for REST. Store the token in config/services.php sourcing from .env. For WebSocket, run a long-running queue worker (php artisan queue:work) with Ratchet/Pawl as the client. Wrap CrossTrade calls as a service class bound in a service provider.
Guzzle or the built-in curl extension?
Both work. Built-in curl is zero-dependency and ideal for scripts/cron. Guzzle adds middleware (retries, logging, exception handling) and is what Laravel's HTTP client wraps. For production trading code, Guzzle's middleware story usually wins — easier to bolt on retry-with-backoff.
Long-running processes: Swoole or RoadRunner?
Both work for keeping a WebSocket open. Swoole rewrites PHP into an async-capable runtime — pair it with workerman or its own coroutine API for the CrossTrade WebSocket. RoadRunner does similar but is Go-backed. Pick based on team familiarity.
Symfony integration?
Yes — use the HttpClient component for REST (zero-dependency, same Bearer-token pattern). For WebSocket, the Ratchet/Pawl client works inside a Symfony Console long-running command. Bind everything as services in services.yaml.
Performance vs Python or Node?
PHP 8.3 with JIT is competitive with Node for typical web/trading workloads. Network-bound calls (CrossTrade REST) don't exercise the JIT much — both languages finish well under CrossTrade's ~50ms round-trip. For pure CPU-bound work (heavy backtest math), the JIT gives PHP a real boost over PHP 7.x.
WordPress integration?
Yes — write a small plugin that calls CrossTrade endpoints and surfaces positions / orders / P&L in the dashboard. Use WordPress transients to cache responses (CrossTrade's 3 req/sec rate limit is easy to hit if every admin page load fires a fresh request).
Can I keep composer dependencies minimal?
Yes — the REST examples use only the built-in curl extension. For WebSocket you do need composer require ratchet/pawl. If you want to avoid the dependency, you can use raw fsockopen / stream_socket_client for a basic WebSocket — works but you re-implement the protocol yourself.
Testing with PHPUnit?
Yes — mock the HTTP client (Guzzle's MockHandler for Guzzle, or wrap curl_exec in a tiny abstraction). For integration tests, hit Sim101 against a test token. CrossTrade's consistent JSON error shape makes assertion-writing straightforward.
Build your first NinjaTrader 8 trading bot in PHP
One bearer token, one URL, every NinjaTrader endpoint. Ship to Sim101 first.