txTrader aims to eliminate the complexity of managing and interacting with multiple trading system APIs, presenting a native python interface.
- Cross-Platform securities trading API management engine
- Provides a trader's eye view of the interaction with the trading system API.
- Decouples business logic from low-level implementation details of interaction with the broker's API
- Maintains internal data structures used to verify each step of the order management / trade execution transaction.
- Supports fault-tolerance by maintaining a continuous connection with the API in the event of application failure.
- Frees trading software design from timing and architectural constraints imposed by the API implementation.
- Built on the mature and reliable twisted python networking engine.
This system aims to present an interface to trading software composed of objects, procedures, and events that fit naturally into the design of an automated trading system. Common trading system APIs often expose implementation details such as message packet parsing, message and field IDs. They often have specific OS and development environment requirements. Their use commonly requires the client application to support advanced programming techniques like blocking, threading, and event handling mechanisms. This design seems to represent the point of view of the trading software implementer. A goal of txTrader is to decouple the application software from strict timing and sequencing requirements.
This software implements interfaces to the API for CQG's CQGNet application and Interactive Brokers' Trader Workstation. A version has been implemented for the Realtick API, but has a dependency on a closed-source gateway. The system provides access to real-time market data, historical pricing, bar charts, order management, execution reports, and position data.
The gateway is built on the twisted python networking engine. Clients can establish a long-lived TCP/IP streaming data connection using the Netstring protocol, and/or utilize a set of JSON-RPC functions. Both services are password protected using basic authentication and a password handshake. Support for TLS connections with server and client certificates is planned.
Common interface code is used to provide a normalized interface to the managed API. While the contents of the returned objects may differ, many fields are common to the supported environments.
Status change events are available on the TCP/IP streaming service. The data are JSON formatted objects.
The txtrader-client
module exposes the server functions to a client program as local python callables.
The txtrader-monitor
module is used to receive asynchronous events from the TCP channel. The object is configured by passing a dict with channel names and python functions to be called when data of the desired type is received.
The JSON-RPC functions may be accessed without using the client library as follows:
curl "http://${TXTRADER_USERNAME}:${TXTRADER_PASSWORD}@${TXTRADER_HOST}:${TXTRADER_HTTP_PORT}/query_orders"
See the client access projects for usage examples.
TxTrader's server daemons depend on external libraries for each configured API:
-
Interactive Brokers
- IbPy python wrappers for IB's java/C++ API
- bootstrap script uses pinned fork at https://github.com/rstms/IbPy
- https://interactivebrokers.github.io
- runs using IB's API gateway in a docker container, or connected to the stand-alone version of the TWS java application
-
CQG
- server runs on Windows
- uses win32com to access CQG's COM API
- http://partners.cqg.com/api-resources
-
RealTick
- uses RTGW Txtrader GateWay running on Linux
- Contact the author or your RealTick customer service agent for API details
The fastest way to get started is to use PyPI
pip install txtrader txtrader-client txtrader-monitor
txtraderd &
docker start rstms/txtrader:latest
At startup of a local process or as a docker container, environment variables are read to set configuration. Each variable has a default value that will be used if it is not present.
To read configuration from a file, use a tool like envdir or cfgdir or a bash script may be used to set the desired variables.
Variable | Description |
---|---|
TXTRADER_USERNAME | txtrader_user |
TXTRADER_PASSWORD | txtrader_pass |
TXTRADER_HTTP_PORT | 50080 |
TXTRADER_TCP_PORT | 50090 |
TXTRADER_DAEMON_REACTOR | poll |
TXTRADER_DAEMON_LOGFILE | - |
TXTRADER_MODE | rtx |
TXTRADER_DAEMON_PIDFILE | '' |
TXTRADER_API_HOST | localhost |
TXTRADER_API_PORT | 51070 |
TXTRADER_API_ACCOUNT | api_account |
TXTRADER_API_TIMEZONE | America/New_York |
TXTRADER_API_ROUTE | DEMO |
TXTRADER_API_CLIENT_ID | 0 |
TXTRADER_ENABLE_TICKER | 0 |
TXTRADER_ENABLE_HIGH_LOW | 1 |
TXTRADER_ENABLE_BARCHART | 1 |
TXTRADER_ENABLE_SYMBOL_BARCHART | 0 |
TXTRADER_ENABLE_SECONDS_TICK | 1 |
TXTRADER_ENABLE_EXCEPTION_HALT | 0 |
TXTRADER_LOG_API_MESSAGES | 0 |
TXTRADER_DEBUG_API_MESSAGES | 0 |
TXTRADER_LOG_CLIENT_MESSAGES | 0 |
TXTRADER_LOG_HTTP_REQUESTS | 1 |
TXTRADER_LOG_HTTP_RESPONSES | 0 |
TXTRADER_LOG_ORDER_UPDATES | 0 |
TXTRADER_TIME_OFFSET | 0 |
TXTRADER_SUPPRESS_ERROR_CODES | 2100 |
TXTRADER_TIMEOUT_DEFAULT | 15 |
TXTRADER_TIMEOUT_ACCOUNT | 15 |
TXTRADER_TIMEOUT_ADDSYMBOL | 15 |
TXTRADER_TIMEOUT_BARCHART | 10 |
TXTRADER_TIMEOUT_ORDER | 300 |
TXTRADER_TIMEOUT_ORDERSTATUS | 3600 |
TXTRADER_TIMEOUT_POSITION | 20 |
TXTRADER_TIMEOUT_TIMER | 10 |
TXTRADER_ENABLE_AUTO_RESET | 1 |
TXTRADER_LOCAL_RESET_TIME | "05:00" |
This version of the sofware is designed to be used on private internal infrastructure. It is NOT intended to be exposed to the public Internet. TxTrader currently doesn't implement HTTPS and the password mechanism is rudimentary. It is strongly recommended that access control be implemented at the network level.
Security mechanisms used in existing deployments include:
- virtual machine private networking
- local private network addressing
- VPN
- docker container networking
- ssh port forwarding
- firewall rules
Contact the author for additional info: mkrueger@rstms.net
The server implements the following JSONRPC calls:
TxTrader Securities Trading API Controller 1.14.25 2020-08-10 02:23:00
add_symbol('symbol')
Request subscription to a symbol for price updates and order entry
cancel_order('id')
Request cancellation of a pending order
del_symbol('symbol')
Delete subscription to a symbol for price updates and order entry
gateway_logoff()
Logoff from gateway
gateway_logon('username', 'password')
logon to gateway
get_order_route() => {'route_name', None | {parameter_name: parameter_value, ...}}
Return current order route as a dict
global_cancel()
Request cancellation of all pending orders
help() => {'command': 'command(parameters) => return', ...}
Return dict containing brief documentation for each command
limit_order('account', 'route', 'symbol', price, quantity) => {'field':, data, ...}
Submit a limit order, returning dict containing new order fields
market_order('account', 'route', 'symbol', quantity) => {'field':, data, ...}
Submit a market order, returning dict containing new order fields
query_account(account, fields) => {'key': (value, currency), ...}
Query account data for account. fields is list of fields to select; None=all fields
query_accounts() => ['account_name', ...]
Return array of account names
query_bars('symbol', bar_period, 'start', 'end')
=> ['Status: OK', [time, open, high, low, close, volume], ...]
Return array containing status strings and lists of bar data if successful
query_execution('id') => {'fieldname': data, ...}
Return dict containing execution report data fields
query_executions() => {'exec_id': {'field': data, ...}, ...}
Return dict keyed by execution id containing dicts of execution report data fields
query_order('id') => {'fieldname': data, ...}
Return dict containing order/ticket status fields for given order id
query_executions() => {'exec_id': {'field': data, ...}, ...}
Return dict keyed by execution id containing dicts of execution report data fields given order_id
query_orders() => {'order_id': {'field': data, ...}, ...}
Return dict keyed by order id containing dicts of order data fields
query_positions() => {'account': {'fieldname': data, ...}, ...}
Return dict keyed by account containing dicts of position data fields
query_symbol('symbol') => {'fieldname': data, ...}
Return dict containing current data for given symbol
query_symbol_bars('symbol') => [[barchart data], ...]
Return array of current live bar data for given symbol
query_symbol_data('symbol') => {'fieldname': data, ...}
Return dict containing rawdata for given symbol
query_symbols() => ['symbol', ...]
Return the list of active symbols
query_tickets() => {'order_id': {'field': data, ...}, ...}
Return dict keyed by order id containing dicts of staged order ticket data fields
set_account('account')
Select current active trading account.
set_order_route(route) => True if success, else False
Set order route data given route {'route_name': {parameter: value, ...} (JSON string will be parsed into a route dict)}
set_primary_exchange(symbol, exchange)
Set primary exchange for symbol (default is SMART), delete mapping if exchange is None.
shutdown(message)
Request server shutdown
stage_market_order('tag', 'account', 'route', 'symbol', quantity) => {'fieldname': data, ...}
Submit a staged market order (displays as staged in GUI, requiring manual aproval), returning dict containing new order fields
status() => 'status string'
return string describing current API connection status
stop_order('account', 'route', 'symbol', price, quantity) => {'field':, data, ...}
Submit a stop order, returning dict containing new order fields
stoplimit_order('account', 'route', 'symbol', stop_price, limit_price, quantity) => {'field':, data, ...}
Submit a stop-limit order, returning dict containing new order fields
time() => 'time string'
Return formatted timestamp string (YYYY-MM-DD HH:MM:SS) matching latest datafeed time update
uptime() => 'uptime string'
Return string showing start time and elapsed time for current server instance
version() => 'version string'
Return string containing release version of current server instance