Official Python SDK for ActTrader Trading API
Project description
ActTrader SDK for Python
Official Python SDK for ActTrader Trading API. This SDK provides a comprehensive interface to interact with ActTrader's REST API and WebSocket streaming services.
Features
- ๐ 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
- ๐ Type Hints - Full Python type hints included
- โก Async Support - Modern async/await API
Installation
pip install acttrader-trading-sdk
Quick Start
Initialize the SDK
from acttrader import ActTrader
# Option 1: Initialize with username and password for digest authentication
client = ActTrader(
base_url='http://rest-api.sysfx.com:18001',
ws_url='ws://stream.sysfx.com:18002', # Legacy: single WebSocket URL
username='your_username',
password='your_password'
)
# Option 2: Initialize with separate WebSocket URLs (recommended)
client = ActTrader(
base_url='http://rest-api.sysfx.com:18001',
order_ws_url='ws://order-stream.sysfx.com:18002', # Order updates stream
price_feed_ws_url='ws://pricefeed-stream.sysfx.com:18003', # Price feed stream
username='your_username',
password='your_password'
)
# Option 3: Initialize with existing token
client = ActTrader(
base_url='http://rest-api.sysfx.com:18001',
order_ws_url='ws://order-stream.sysfx.com:18002',
price_feed_ws_url='ws://pricefeed-stream.sysfx.com:18003',
token='your_existing_token'
)
# Authenticate and initialize symbol cache (required for lots-based trading)
await client.auth.get_token(60)
await client.initialize_symbol_cache() # Auto-refreshes every 24 hours
API Reference
Authentication
Get Token
# Get authentication token (requires username/password)
result = await client.auth.get_token(60) # 60 minutes lifetime
token = result.result
print('Token:', token)
# Token is automatically stored in the client
Logout
# Revoke current token
await client.auth.logout()
Reset Password
# Reset user password (sent via email)
await client.auth.reset_password('user_login_id')
Account Management
Get Accounts
# Get all accounts for current user
result = await client.account.get_accounts()
accounts = result.result
for account in accounts:
print(f"Account {account.AccountID}:")
print(f" Balance: {account.Balance} {account.Currency}")
print(f" Used Margin: {account.UsedMargin}")
Change Password
# Change user password
await client.account.change_password('old_password', 'new_password')
Market Data
Get Instruments
# Get all active instruments
result = await client.market.get_instruments('Y')
instruments = result.result
for instrument in instruments:
print(f"{instrument.Name} ({instrument.Type})")
Get Symbols
# Get trading symbols with current prices
result = await client.market.get_symbols()
symbols = result.result
for symbol in symbols:
print(f"{symbol.Symbol}: Bid {symbol.Sell}, Ask {symbol.Buy}")
Get Detailed Symbol Information
# Get symbols with detailed information (margin, commission, etc.)
result = await client.market.get_symbols_detailed()
details = result.result
for detail in details:
print(f"{detail.Pair_label}:")
print(f" Contract Size: {detail.Contract_size}")
print(f" Min Volume: {detail.Min_volume}")
print(f" Margin Rate: {detail.Margin_settings.Rate}%")
Get Price Shifts
# Get price shifts for instruments
result = await client.market.get_shifts()
shifts = result.result
Trading
Place Market Order
# Simple order without stop/limit/trail
result = await client.trading.place_market_order({
'symbol': 'EURUSD',
'quantity': 100000, # Direct quantity
'side': 1, # 1 = buy, 0 = sell
'account': 100
})
# ๐ฅ NEW: Order with LOTS (recommended for forex trading)
result2 = await client.trading.place_market_order({
'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)
result3 = await client.trading.place_market_order({
'symbol': 'EURUSD',
'lots': 0.1, # 0.1 lots = 10,000 quantity
'side': 1,
'account': 100
})
print('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.initialize_symbol_cache()
Place Pending Order
# Place a pending order (Entry Stop or Entry Limit)
result = await client.trading.place_pending_order({
'symbol': 'EURUSD',
'quantity': 1000,
'side': 0, # 0 = sell, 1 = buy
'account': 100,
'price': 1.0950,
'stop': 1.1000,
'limit': 1.0900
})
Place Stop/Limit Orders
# Place stop loss on existing trade
await client.trading.place_stop({
'trade': 12345,
'price': 1.0800
})
# Place stop using pips instead of price
await client.trading.place_stop({
'trade': 12345,
'pips': 50
})
# Place take profit on existing trade
await client.trading.place_limit({
'trade': 12345,
'price': 1.1200
})
# Place trailing stop
await client.trading.place_trail({
'trade': 12345,
'trail': 10 # 10 pips
})
Modify Order
# Modify pending order
await client.trading.modify_order(
247668792, # Order ID
1.0080, # New price
2000 # New quantity
)
Cancel Order
# Cancel pending order
await client.trading.cancel_order(247668792)
Close Trade
# Close open position
result = await client.trading.close_trade(
247568770, # Trade ID
1000, # Quantity to close
'N' # Hedge: 'Y' or 'N'
)
print('Closing order:', result.result.OrderID)
Hedge Trade
# Hedge an open position
result = await client.trading.hedge_trade(
247568770, # Trade ID
1000 # Quantity to hedge
)
Get Open Orders
# Get all open orders
result = await client.trading.get_open_orders()
orders = result.result
for order in orders:
print(f"Order {order.OrderID}:")
print(f" {order.Symbol} {order.Side === 1 ? 'BUY' : 'SELL'}")
print(f" Quantity: {order.Quantity} @ {order.Price}")
print(f" Type: {order.Type}, Status: {order.Pending}")
Get Open Trades
# Get all open positions
result = await client.trading.get_open_trades()
trades = result.result
for trade in trades:
print(f"Trade {trade.TradeID}:")
print(f" {trade.Symbol} {trade.Side === 1 ? 'BUY' : 'SELL'}")
print(f" Quantity: {trade.Quantity} @ {trade.Price}")
print(f" Commission: {trade.Commission}")
Get Trade History
# Get historical trades
result = await client.trading.get_trade_history({
'from_date': '2021-04-01T00:00',
'till': '2021-04-30T23:59',
'account': 100
})
history = result.result
for trade in history:
print(f"Trade {trade.TradeID}:")
print(f" Open: {trade.OpenPrice} -> Close: {trade.ClosePrice}")
print(f" P&L: {trade.ProfitLoss}")
Get Removed Orders
# Get removed orders history
result = await client.trading.get_removed_orders({
'from_date': '2021-04-01T00:00',
'till': '2021-04-30T23:59',
'account': 100
})
Alerts (Deprecated)
โ ๏ธ Note: The alert module is deprecated. Please check with ActTrader for alternative solutions.
# Get active alerts
result = await client.alert.get_alerts()
# Create alert
alert_result = await client.alert.create_alert(
'EUR/USD', # Symbol
1.1800, # Price
'BID', # Type: 'BID' or 'ASK'
'Target price' # Commentary
)
# Modify alert
await client.alert.modify_alert(123, 1.1850, 'BID', 'Updated target')
# Remove alert
await client.alert.remove_alert(123)
# Get triggered alerts
triggered = await client.alert.get_triggered_alerts(
'202109010000', # From date (YYYYMMDDHH24MI)
'202109302359' # Till date (YYYYMMDDHH24MI)
)
WebSocket Streaming
Real-time market data and trading events via WebSocket. The SDK supports two separate WebSocket streams for optimal performance and separation of concerns:
- Order Updates Stream - Handles order events, trade events, account updates, and legacy ticker data
- Price Feed Stream - Handles price feed messages with OHLC data
Dual WebSocket Setup (Recommended)
# Create separate streaming clients
order_stream = client.stream_orders() # Order updates
price_stream = client.stream_price_feed() # Price feed data
# Connect to order updates stream
order_stream.on('connected', lambda: print('Order stream connected'))
order_stream.on('order', lambda data: print('Order event:', data))
order_stream.on('trade', lambda data: print('Trade event:', data))
await order_stream.connect()
await order_stream.subscribe(['EURUSD', 'GBPUSD'])
# Connect to price feed stream
price_stream.on('connected', lambda: print('Price feed stream connected'))
price_stream.on('pricefeed', lambda data: print('Price feed with OHLC:', data))
await price_stream.connect()
await price_stream.subscribe(['EURUSD', 'GBPUSD'])
Legacy Single WebSocket (Deprecated)
# Create streaming client (legacy approach)
stream = client.stream()
# Connect to WebSocket
await stream.connect()
# Handle connection events
stream.on('connected', lambda: print('Connected to streaming server'))
stream.on('disconnected', lambda: print('Disconnected from streaming server'))
stream.on('error', lambda error: print('WebSocket error:', error))
# Subscribe to symbols
await stream.subscribe(['EURUSD', 'GBPUSD', 'USDJPY'])
# Handle ticker updates (price changes) - Legacy format
stream.on('ticker', lambda data: print('Ticker update:', data))
# Handle price feed updates (new format with OHLC data)
stream.on('pricefeed', lambda data: print('Price feed update:', data))
# Handle order book updates
stream.on('orderbook', lambda data: print('Order book update:', data))
# Handle order events (insert/update/delete)
stream.on('order', lambda data: print('Order event:', data))
# Handle account balance updates
stream.on('account', lambda data: print('Account update:', data))
# Handle trade events
stream.on('trade', lambda data: print('Trade event:', data))
# Handle alert triggers
stream.on('alert', lambda data: print('Alert triggered:', data))
# Handle equity warnings
stream.on('equity_warning', lambda data: print('Equity Warning!', data))
# Unsubscribe from symbols
await stream.unsubscribe(['USDJPY'])
# Disconnect
await stream.disconnect()
Message Formats
The SDK supports two WebSocket message formats:
1. Legacy Ticker Format (Order Updates)
# Event: 'ticker'
{
"event": "ticker",
"payload": [
{
"m": "EURUSD",
"time": "2025-10-15T11:25:34.092Z",
"bid": 1.16295,
"ask": 1.16302
}
]
}
2. Price Feed Format (Market Data with OHLC)
# Event: 'pricefeed'
{
"m": "ticker",
"d": [
{
"m": "EURUSD",
"time": "2025-10-15T11:25:34.092Z",
"bid": 1.16295,
"ask": 1.16302,
"day_open": 1.16064,
"day_high": 1.16453,
"day_low": 1.16012
}
]
}
Usage Recommendation:
- Use
tickerevent for order updates and basic price data - Use
pricefeedevent for market data analysis with OHLC information
Complete Example
import asyncio
from acttrader import ActTrader
async def main():
# Initialize client
client = ActTrader(
base_url='http://rest-api.sysfx.com:18001',
ws_url='ws://stream.sysfx.com:18002',
username='your_username',
password='your_password'
)
try:
# Get authentication token
token_result = await client.auth.get_token(60)
print('Authenticated with token:', token_result.result)
# Initialize symbol cache (required for lots-based trading)
await client.initialize_symbol_cache()
print('Symbol cache initialized')
# Get accounts
accounts_result = await client.account.get_accounts()
accounts = accounts_result.result
print(f'Found {len(accounts)} accounts')
# Get market symbols
symbols_result = await client.market.get_symbols()
symbols = symbols_result.result
print(f'Available symbols: {len(symbols)}')
# Place a market order using LOTS (recommended)
order_result = await client.trading.place_market_order({
'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'
})
print('Order placed:', order_result.result.OrderID)
# Get open trades
trades_result = await client.trading.get_open_trades()
print('Open trades:', len(trades_result.result))
# Start streaming
stream = client.stream()
def on_connected():
print('Streaming connected')
asyncio.create_task(stream.subscribe(['EURUSD', 'GBPUSD']))
def on_ticker(data):
print('Price update:', data)
stream.on('connected', on_connected)
stream.on('ticker', on_ticker)
await stream.connect()
# Keep process running
await asyncio.sleep(30)
await stream.disconnect()
await client.auth.logout()
except Exception as error:
print('Error:', error)
if __name__ == '__main__':
asyncio.run(main())
Error Handling
All API methods return a response object with the following structure:
class ApiResponse:
success: bool
message: Optional[str] = None
result: Optional[Any] = None
Example error handling:
try:
result = await client.trading.place_market_order({
'symbol': 'EURUSD',
'quantity': 1000,
'side': 1,
'account': 100
})
if result.success:
print('Order ID:', result.result.OrderID)
else:
print('Order failed:', result.message)
except Exception as error:
print('API Error:', error)
Type Hints
This SDK is written with full Python type hints:
from acttrader import ActTrader, Account, Symbol, Order, Trade, OrderSide, OrderType, ApiResponse
# Full type safety
client = ActTrader({...})
result: ApiResponse[List[Account]] = await client.account.get_accounts()
accounts: List[Account] = result.result
API Endpoints
All dates are in Eastern Time (EST/EDT)
REST API
- Base URL:
http://rest-api.sysfx.com:18001/ - API Version: v2
- Format:
/api/v2/{module}/{endpoint}
WebSocket
- URL:
ws://stream.sysfx.com:18002/ - Connection:
ws://stream.sysfx.com:18002/ws?token={your_token}
Development
Build from Source
# Install dependencies
pip install -r requirements.txt
# Install in development mode
pip install -e .
Project Structure
acttrader-trading-sdk/
โโโ acttrader/
โ โโโ __init__.py # Main SDK entry point
โ โโโ main.py # Main ActTrader class
โ โโโ client.py # HTTP client with authentication
โ โโโ types.py # Python type definitions
โ โโโ digest_auth.py # Digest authentication
โ โโโ symbol_cache.py # Symbol cache functionality
โ โโโ modules/
โ โโโ __init__.py # Module exports
โ โโโ auth.py # Authentication module
โ โโโ account.py # Account management module
โ โโโ market.py # Market data module
โ โโโ trading.py # Trading operations module
โ โโโ alert.py # Alerts module (deprecated)
โ โโโ streaming.py # WebSocket streaming client
โโโ examples/ # Example scripts
โโโ tests/ # Test suite
โโโ setup.py # Package setup
โโโ requirements.txt # Dependencies
โโโ README.md # This file
License
ISC
Support
For API documentation and support, please contact ActTrader.
Contributing
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).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file acttrader_trading_sdk-1.0.1.tar.gz.
File metadata
- Download URL: acttrader_trading_sdk-1.0.1.tar.gz
- Upload date:
- Size: 31.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f3a7a753459ca53b43bf4e5ab8bf166fecf730bb21d1e38baf51e5cd97b9600
|
|
| MD5 |
1999afc765c63b071799c14100e2e9bc
|
|
| BLAKE2b-256 |
06ff3fbccf8e91543db703abaeb060782781f94f13ea49a26675622c649099c1
|
File details
Details for the file acttrader_trading_sdk-1.0.1-py3-none-any.whl.
File metadata
- Download URL: acttrader_trading_sdk-1.0.1-py3-none-any.whl
- Upload date:
- Size: 29.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f1ba7c225da23e26218487647df985738be4538fd40be402d09531b0f62f4c3
|
|
| MD5 |
5cb174e8f87fc7a7a490fbbe556bba79
|
|
| BLAKE2b-256 |
eec1c83bf03160365347354ca6e06fa49a3d54b34785faaf8525047fd4ef1d9c
|