Ultra-low latency Java TCP client for IonTrader
Real-time market data, trade execution, balance & user management via TCP.
Server-to-Server (S2S) integration — ideal for brokers, CRMs, HFT bots, and back-office systems.
| Feature | Description |
|---|---|
| TCP S2S | Direct TCP connection — no HTTP overhead |
| Real-time Events | Quotes, trades, balance, user & symbol updates |
| Optimized Subscribe | platform.subscribe() / unsubscribe() |
| Dynamic Commands | platform.call("AddUser", data) |
| Auto-reconnect | Robust reconnection with backoff |
| Event Filtering | ignoreEvents, per-symbol listeners |
| extID Tracking | Reliable command responses |
| JSON Repair | Handles malformed packets gracefully |
| Thread-Safe | ConcurrentHashMap, CompletableFuture |
<dependency>
<groupId>com.iontrader</groupId>
<artifactId>ion-server-api-java</artifactId>
<version>1.0.0</version>
</dependency>implementation 'com.iontrader:ion-server-api-java:1.0.0'git clone https://github.com/iontrader/server-api-java
cd server-api-java
mvn clean installimport com.iontrader.IONPlatform;
import java.util.List;
import java.util.Map;
public class Example {
public static void main(String[] args) {
// Initialize with minimal config
IONPlatform platform = new IONPlatform(
"broker.iontrader.com:8080", // Host:port
"my-trading-bot", // Name
Map.of("autoSubscribe", List.of("EURUSD", "BTCUSD")),
null, null,
"your-jwt-auth-token"
);
// Real-time quotes
platform.on("quote", q -> {
System.out.printf("%s: %s/%s%n",
q.get("symbol").asText(),
q.get("bid").asDouble(),
q.get("ask").asDouble()
);
});
// Trade events
platform.on("trade:event", e -> {
var d = e.get("data");
String cmd = d.get("cmd").asInt() == 0 ? "BUY" : "SELL";
System.out.printf("#%s %s %s %s%n",
d.get("order").asText(),
cmd,
d.get("volume").asDouble(),
d.get("symbol").asText()
);
});
// Subscribe to new symbol
platform.subscribe("XAUUSD");
// Create user
platform.call("AddUser", Map.of(
"name", "John Doe",
"group", "VIP",
"leverage", 500,
"email", "john@example.com"
)).thenAccept(resp -> System.out.println("User created: " + resp));
// Graceful shutdown
platform.destroy();
}
}| Event | Description | Example Data |
|---|---|---|
quote |
Real-time tick | { symbol: "EURUSD", bid: 1.085, ask: 1.086 } |
quote:SYMBOL |
Per-symbol | quote:EURUSD |
notify |
System alerts | { message, level, code, data } |
notify:LEVEL |
By level | notify:20 (warning) |
trade:event |
Order open/close/modify | { order, profit, volume, symbol } |
trade:event:LOGIN |
Per-user trades | trade:event:12345 |
balance:event |
Balance & margin update | { equity, margin_level, balance } |
balance:event:LOGIN |
Per-user balance | balance:event:12345 |
user:event |
User profile change | { leverage, group, name } |
user:event:LOGIN |
Per-user updates | user:event:12345 |
symbol:event |
Symbol settings update | { spread, swap_long, swap_short } |
symbol:event:SYMBOL |
Per-symbol updates | symbol:event:EURUSD |
group:event |
Group config change | { default_leverage, margin_call } |
group:event:GROUP |
Per-group updates | group:event:VIP |
symbols:reindex |
Symbol index map | [[symbol, sym_index, sort_index], ...] |
security:reindex |
Security group map | [[sec_index, sort_index], ...] |
| Method | Description | Returns |
|---|---|---|
subscribe(channels) |
Fast subscribe to symbols | CompletableFuture<JsonNode> |
unsubscribe(channels) |
Fast unsubscribe | CompletableFuture<JsonNode> |
call(command, data) |
Execute any command | CompletableFuture<JsonNode> |
send(payload) |
Low-level send | CompletableFuture<JsonNode> |
on(event, listener) |
Register event listener | IONPlatform (chainable) |
destroy() |
Close connection | void |
// Single symbol
platform.subscribe("GBPUSD")
.thenAccept(resp -> System.out.println("Subscribed"));
// Multiple symbols
platform.subscribe(List.of("GBPUSD", "USDJPY"))
.thenAccept(resp -> System.out.println("Subscribed to all"));
// Unsubscribe
platform.unsubscribe("BTCUSD")
.thenAccept(resp -> System.out.println("Unsubscribed"));platform.call("GetUsers", Map.of())
.thenAccept(resp -> {
System.out.println("Users: " + resp);
})
.exceptionally(err -> {
System.err.println("Error: " + err.getMessage());
return null;
});platform.on("balance:event", e -> {
var data = e.get("data");
System.out.printf("User %s: Equity = %s%n",
data.get("login").asText(),
data.get("equity").asDouble()
);
});
// Listen to specific user
platform.on("balance:event:12345", e -> {
System.out.println("User 12345 balance updated");
});// Listen to specific symbol
platform.on("quote:EURUSD", q -> {
System.out.printf("EUR/USD: %s%n", q.get("bid").asDouble());
});
// Listen to all quotes
platform.on("quote", q -> {
System.out.printf("%s: %s/%s%n",
q.get("symbol").asText(),
q.get("bid").asDouble(),
q.get("ask").asDouble()
);
});platform.on("notify", n -> {
String level = switch (n.get("level").asInt()) {
case 10 -> "INFO";
case 20 -> "WARN";
case 30 -> "ERROR";
case 40 -> "PROMO";
default -> "UNKNOWN";
};
System.out.printf("[%s] %s%n", level, n.get("message").asText());
});
// Listen to specific level
platform.on("notify:30", n -> {
System.err.println("ERROR: " + n.get("message").asText());
});// Symbol updates (spread, swap, etc.)
platform.on("symbol:event", e -> {
var d = e.get("data");
System.out.printf("Symbol %s updated: spread=%s%n",
d.get("symbol").asText(),
d.has("spread") ? d.get("spread").asInt() : "N/A"
);
});
// Group updates
platform.on("group:event", e -> {
var d = e.get("data");
System.out.printf("Group %s: leverage=%s%n",
d.get("group").asText(),
d.get("default_leverage").asInt()
);
});| Option | Type | Default | Description |
|---|---|---|---|
autoSubscribe |
List<String> |
[] |
Auto-subscribe on connect |
ignoreEvents |
Boolean |
false |
Disable all event emission |
prefix |
String |
"ion" |
Event prefix (reserved) |
mode |
String |
"live" |
Environment: "live" or "demo" |
IONPlatform platform = new IONPlatform(
"broker.iontrader.com:8080",
"my-bot",
Map.of(
"autoSubscribe", List.of("EURUSD", "GBPUSD"),
"ignoreEvents", false,
"mode", "demo"
),
null, null,
"your-jwt-token"
);platform.call("AddUser", Map.of("name", "John"))
.thenAccept(resp -> {
if (resp.has("error")) {
System.err.println("Error: " + resp.get("error").asText());
} else {
System.out.println("Success: " + resp);
}
})
.exceptionally(err -> {
System.err.println("Request failed: " + err.getMessage());
return null;
});- Thread-safe collections:
ConcurrentHashMap,CopyOnWriteArrayList - Non-blocking I/O: Netty event loop
- Async responses:
CompletableFuture<JsonNode> - Event listeners can be called from any thread
- TCP API: https://iontrader.com/tcp
- Client API: https://iontrader.com/client-api
- FIX API: https://iontrader.com/fix-api
- Java 17 or higher
- Valid IonTrader JWT token
- Dependencies:
- Jackson 2.17.2+ (JSON)
- Netty 4.1.114+ (TCP)
git clone https://github.com/iontrader/server-api-java
cd server-api-java
mvn clean installRun example:
mvn exec:java -Dexec.mainClass="com.iontrader.example.ConsoleExample"Distributed under the MIT License.
See LICENSE for more information.
Made with passion for high-frequency trading