Official Node.js SDK for ActTrader Trading API. This SDK provides a comprehensive interface to interact with ActTrader's REST API and WebSocket streaming services.
- 🔐 Authentication - Digest authentication and token-based session management
- 💰 Account Management - Access account information and manage settings
- 📊 Market Data - Get real-time and historical market data, symbols, and instruments
- 📈 Trading Operations - Place, modify, and cancel orders; manage positions
- 🎯 Lots-Based Trading - Trade with lots (auto-converts to quantity using contract size)
- 💾 Symbol Cache - Auto-refreshing symbol cache (24-hour intervals)
- 🔔 Alerts - Create and manage price alerts (deprecated)
- 🌊 WebSocket Streaming - Real-time market data and trading events
- 📘 TypeScript Support - Full TypeScript definitions included
- ⚡ Promise-based - Modern async/await API
npm install acttrader-sdkimport { ActTrader } from 'acttrader-sdk';
// Option 1: Initialize with username and password for digest authentication
const client = new ActTrader({
baseUrl: 'http://rest-api.sysfx.com:18001',
wsUrl: 'ws://stream.sysfx.com:18002',
username: 'your_username',
password: 'your_password'
});
// Option 2: Initialize with existing token
const client = new ActTrader({
baseUrl: 'http://rest-api.sysfx.com:18001',
wsUrl: 'ws://stream.sysfx.com:18002',
token: 'your_existing_token'
});
// Authenticate and initialize symbol cache (required for lots-based trading)
await client.auth.getToken(60);
await client.initializeSymbolCache(); // Auto-refreshes every 24 hours// Get authentication token (requires username/password)
const result = await client.auth.getToken(60); // 60 minutes lifetime
const token = result.result;
console.log('Token:', token);
// Token is automatically stored in the client// Revoke current token
await client.auth.logout();// Reset user password (sent via email)
await client.auth.resetPassword('user_login_id');// Get all accounts for current user
const result = await client.account.getAccounts();
const accounts = result.result;
accounts.forEach(account => {
console.log(`Account ${account.AccountID}:`);
console.log(` Balance: ${account.Balance} ${account.Currency}`);
console.log(` Used Margin: ${account.UsedMargin}`);
});// Change user password
await client.account.changePassword('old_password', 'new_password');// Get all active instruments
const result = await client.market.getInstruments('Y');
const instruments = result.result;
instruments.forEach(instrument => {
console.log(`${instrument.Name} (${instrument.Type})`);
});// Get trading symbols with current prices
const result = await client.market.getSymbols();
const symbols = result.result;
symbols.forEach(symbol => {
console.log(`${symbol.Symbol}: Bid ${symbol.Sell}, Ask ${symbol.Buy}`);
});// Get symbols with detailed information (margin, commission, etc.)
const result = await client.market.getSymbolsDetailed();
const details = result.result;
details.forEach(detail => {
console.log(`${detail['Pair label']}:`);
console.log(` Contract Size: ${detail['Contract size']}`);
console.log(` Min Volume: ${detail['Min volume']}`);
console.log(` Margin Rate: ${detail['Margin settings'].Rate}%`);
});// Get price shifts for instruments
const result = await client.market.getShifts();
const shifts = result.result;// Simple order without stop/limit/trail
const result = await client.trading.placeMarketOrder({
symbol: 'EURUSD',
quantity: 100000, // Direct quantity
side: 1, // 1 = buy, 0 = sell
account: 100
});
// 🔥 NEW: Order with LOTS (recommended for forex trading)
const result2 = await client.trading.placeMarketOrder({
symbol: 'EURUSD',
lots: 1.0, // SDK converts to quantity automatically
side: 1,
account: 100,
stop: 1.0800, // Optional - stop loss
limit: 1.1200, // Optional - take profit
trail: 10, // Optional - trailing stop (in pips)
commentary: 'Optional comment'
});
// Mini lot (0.1 lots)
const result3 = await client.trading.placeMarketOrder({
symbol: 'EURUSD',
lots: 0.1, // 0.1 lots = 10,000 quantity
side: 1,
account: 100
});
console.log('Order placed:', result.result.OrderID);Note:
- Use either
lotsorquantity, not both stop,limit,trail, andcommentaryare all optional- Symbol cache must be initialized to use lots:
await client.initializeSymbolCache()
// Place a pending order (Entry Stop or Entry Limit)
const result = await client.trading.placePendingOrder({
symbol: 'EURUSD',
quantity: 1000,
side: 0, // 0 = sell, 1 = buy
account: 100,
price: 1.0950,
stop: 1.1000,
limit: 1.0900
});// Place stop loss on existing trade
await client.trading.placeStop({
trade: 12345,
price: 1.0800
});
// Place stop using pips instead of price
await client.trading.placeStop({
trade: 12345,
pips: 50
});
// Place take profit on existing trade
await client.trading.placeLimit({
trade: 12345,
price: 1.1200
});
// Place trailing stop
await client.trading.placeTrail({
trade: 12345,
trail: 10 // 10 pips
});// Modify pending order
await client.trading.modifyOrder(
247668792, // Order ID
1.0080, // New price
2000 // New quantity
);// Cancel pending order
await client.trading.cancelOrder(247668792);// Close open position
const result = await client.trading.closeTrade(
247568770, // Trade ID
1000, // Quantity to close
'N' // Hedge: 'Y' or 'N'
);
console.log('Closing order:', result.result.OrderID);// Hedge an open position
const result = await client.trading.hedgeTrade(
247568770, // Trade ID
1000 // Quantity to hedge
);// Get all open orders
const result = await client.trading.getOpenOrders();
const orders = result.result;
orders.forEach(order => {
console.log(`Order ${order.OrderID}:`);
console.log(` ${order.Symbol} ${order.Side === 1 ? 'BUY' : 'SELL'}`);
console.log(` Quantity: ${order.Quantity} @ ${order.Price}`);
console.log(` Type: ${order.Type}, Status: ${order.Pending}`);
});// Get all open positions
const result = await client.trading.getOpenTrades();
const trades = result.result;
trades.forEach(trade => {
console.log(`Trade ${trade.TradeID}:`);
console.log(` ${trade.Symbol} ${trade.Side === 1 ? 'BUY' : 'SELL'}`);
console.log(` Quantity: ${trade.Quantity} @ ${trade.Price}`);
console.log(` Commission: ${trade.Commission}`);
});// Get historical trades
const result = await client.trading.getTradeHistory({
from: '2021-04-01T00:00',
till: '2021-04-30T23:59',
account: 100
});
const history = result.result;
history.forEach(trade => {
console.log(`Trade ${trade.TradeID}:`);
console.log(` Open: ${trade.OpenPrice} -> Close: ${trade.ClosePrice}`);
console.log(` P&L: ${trade.ProfitLoss}`);
});// Get removed orders history
const result = await client.trading.getRemovedOrders({
from: '2021-04-01T00:00',
till: '2021-04-30T23:59',
account: 100
});// Get active alerts
const result = await client.alert.getAlerts();
// Create alert
const alertResult = await client.alert.createAlert(
'EUR/USD', // Symbol
1.1800, // Price
'BID', // Type: 'BID' or 'ASK'
'Target price' // Commentary
);
// Modify alert
await client.alert.modifyAlert(123, 1.1850, 'BID', 'Updated target');
// Remove alert
await client.alert.removeAlert(123);
// Get triggered alerts
const triggered = await client.alert.getTriggeredAlerts(
'202109010000', // From date (YYYYMMDDHH24MI)
'202109302359' // Till date (YYYYMMDDHH24MI)
);Real-time market data and trading events via WebSocket.
// Create streaming client
const stream = client.stream();
// Connect to WebSocket
stream.connect();
// Handle connection events
stream.on('connected', () => {
console.log('Connected to streaming server');
// Subscribe to symbols
stream.subscribe(['EURUSD', 'GBPUSD', 'USDJPY']);
});
stream.on('disconnected', () => {
console.log('Disconnected from streaming server');
});
stream.on('error', (error) => {
console.error('WebSocket error:', error);
});
// Handle ticker updates (price changes)
stream.on('ticker', (data) => {
data.forEach(tick => {
console.log(`${tick.m}: Bid ${tick.bid}, Ask ${tick.ask}`);
});
});
// Handle order book updates
stream.on('orderbook', (data) => {
data.forEach(book => {
console.log(`${book.m} Order Book:`);
console.log(' Buy:', book.buy);
console.log(' Sell:', book.sell);
});
});
// Handle order events (insert/update/delete)
stream.on('order', (data) => {
console.log('Order event:', data.Action); // 'I', 'U', or 'D'
console.log('Order ID:', data.OrderID);
console.log('Symbol:', data.Symbol);
});
// Handle account balance updates
stream.on('account', (data) => {
console.log('Account update:', data.AccountID);
console.log('Balance:', data.Balance);
console.log('Used Margin:', data.UsedMargin);
});
// Handle trade events
stream.on('trade', (data) => {
console.log('Trade event:', data.Action);
console.log('Trade ID:', data.TradeID);
console.log('Price:', data.Price);
});
// Handle alert triggers
stream.on('alert', (data) => {
console.log('Alert triggered:', data.AlertID);
console.log('Symbol:', data.Symbol);
console.log('Price:', data.Price);
});
// Handle equity warnings
stream.on('equity_warning', (data) => {
console.log('Equity Warning!');
console.log('Account:', data.AccountID);
console.log('Equity:', data.Equity);
console.log('Used Margin:', data.UsedMargin);
});
// Unsubscribe from symbols
stream.unsubscribe(['USDJPY']);
// Disconnect
stream.disconnect();import { ActTrader } from 'acttrader-sdk';
async function main() {
// Initialize client
const client = new ActTrader({
baseUrl: 'http://rest-api.sysfx.com:18001',
wsUrl: 'ws://stream.sysfx.com:18002',
username: 'your_username',
password: 'your_password'
});
try {
// Get authentication token
const tokenResult = await client.auth.getToken(60);
console.log('Authenticated with token:', tokenResult.result);
// Initialize symbol cache (required for lots-based trading)
await client.initializeSymbolCache();
console.log('Symbol cache initialized');
// Get accounts
const accountsResult = await client.account.getAccounts();
const accounts = accountsResult.result;
console.log(`Found ${accounts.length} accounts`);
// Get market symbols
const symbolsResult = await client.market.getSymbols();
const symbols = symbolsResult.result;
console.log(`Available symbols: ${symbols.length}`);
// Place a market order using LOTS (recommended)
const orderResult = await client.trading.placeMarketOrder({
symbol: 'EURUSD',
lots: 0.1, // 0.1 lots (auto-converted to quantity)
side: 1, // Buy
account: accounts[0].AccountID,
stop: 1.0800, // Stop loss
limit: 1.1200, // Take profit
commentary: 'Test order'
});
console.log('Order placed:', orderResult.result.OrderID);
// Get open trades
const tradesResult = await client.trading.getOpenTrades();
console.log('Open trades:', tradesResult.result.length);
// Start streaming
const stream = client.stream();
stream.on('connected', () => {
console.log('Streaming connected');
stream.subscribe(['EURUSD', 'GBPUSD']);
});
stream.on('ticker', (data) => {
console.log('Price update:', data);
});
stream.connect();
// Keep process running
process.on('SIGINT', async () => {
stream.disconnect();
await client.auth.logout();
process.exit();
});
} catch (error) {
console.error('Error:', error);
}
}
main();All API methods return a response object with the following structure:
interface ApiResponse<T> {
success: boolean;
message?: string;
result?: T;
}Example error handling:
try {
const result = await client.trading.placeMarketOrder({
symbol: 'EURUSD',
quantity: 1000,
side: 1,
account: 100
});
if (result.success) {
console.log('Order ID:', result.result.OrderID);
} else {
console.error('Order failed:', result.message);
}
} catch (error) {
console.error('API Error:', error.message);
}This SDK is written in TypeScript and includes comprehensive type definitions:
import {
ActTrader,
Account,
Symbol,
Order,
Trade,
OrderSide,
OrderType,
ApiResponse
} from 'acttrader-sdk';
// Full type safety
const client = new ActTrader({ /* config */ });
const result: ApiResponse<Account[]> = await client.account.getAccounts();
const accounts: Account[] | undefined = result.result;All dates are in Eastern Time (EST/EDT)
- Base URL:
http://rest-api.sysfx.com:18001/ - API Version: v2
- Format:
/api/v2/{module}/{endpoint}
- URL:
ws://stream.sysfx.com:18002/ - Connection:
ws://stream.sysfx.com:18002/ws?token={your_token}
# Install dependencies
npm install
# Build TypeScript
npm run build
# Output in dist/acttrader-sdk/
├── src/
│ ├── client.ts # HTTP client with authentication
│ ├── types.ts # TypeScript type definitions
│ ├── index.ts # Main SDK entry point
│ └── modules/
│ ├── auth.ts # Authentication module
│ ├── account.ts # Account management module
│ ├── market.ts # Market data module
│ ├── trading.ts # Trading operations module
│ ├── alert.ts # Alerts module (deprecated)
│ └── streaming.ts # WebSocket streaming client
├── dist/ # Compiled JavaScript (generated)
├── package.json
├── tsconfig.json
└── README.md
ISC
For API documentation and support, please contact ActTrader.
Contributions are welcome! Please ensure your code follows the existing style and includes appropriate tests.
Note: This SDK requires valid ActTrader credentials and access to ActTrader API servers. All dates/times are in Eastern Time (EST/EDT).