In this article by James Ma Weiming, author of the book Mastering Python for Finance , we will see how algorithmic trading automates the systematic trading process, where orders are executed at the best price possible based on a variety of factors, such as pricing, timing, and volume. Some brokerage firms may offer an application programming interface (API) as part of their service offering to customers who wish to deploy their own trading algorithms. For developing an algorithmic trading system, it must be highly robust and handle any point of failure during the order execution. Network configuration, hardware, memory management and speed, and user experience are some factors to be considered when designing a system in executing orders. Designing larger systems inevitably add complexity to the framework.
As soon as a position in a market is opened, it is subjected to various types of risk, such as market risk. To preserve the trading capital as much as possible, it is important to incorporate risk management measures to the trading system. Perhaps the most common risk measure used in the financial industry is the value-at-risk (VaR) technique. We will discuss the beauty and flaws of VaR, and how it can be incorporated into our trading system that we will develop in this article.
In this article, we will cover the following topics:
In the 1990s, exchanges had already begun to use electronic trading systems. By 1997, 44 exchanges worldwide used automated systems for trading futures and options with more exchanges in the process of developing automated technology. Exchanges such as the Chicago Board of Trade (CBOT) and the London International Financial Futures and Options Exchange (LIFFE) used their electronic trading systems as an after-hours complement to traditional open outcry trading in pits, giving traders 24-hour access to the exchange's risk management tools. With improvements in technology, technology-based trading became less expensive, fueling the growth of trading platforms that are faster and powerful. Higher reliability of order execution and lower rates of message transmission error deepened the reliance of technology by financial institutions. The majority of asset managers, proprietary traders, and market makers have since moved from the trading pits to electronic trading floors.
As systematic or computerized trading became more commonplace, speed became the most important factor in determining the outcome of a trade. Quants utilizing sophisticated fundamental models are able to recompute fair values of trading products on the fly and execute trading decisions, enabling them to reap profits at the expense of fundamental traders using traditional tools. This gave way to the term high-frequency trading (HFT) that relies on fast computers to execute the trading decisions before anyone else can. HFT has evolved into a billion-dollar industry.
Algorithmic trading refers to the automation of the systematic trading process, where the order execution is heavily optimized to give the best price possible. It is not part of the portfolio allocation process.
Banks, hedge funds, brokerage firms, clearing firms, and trading firms typically have their servers placed right next to the electronic exchange to receive the latest market prices and to perform the fastest order execution where possible. They bring enormous trading volumes to the exchange. Anyone who wishes to participate in low-latency, high-volume trading activities, such as complex event processing or capturing fleeting price discrepancies, by acquiring exchange connectivity may do so in the form of co-location, where his or her server hardware can be placed on a rack right next to the exchange for a fee.
The Financial Information Exchange (FIX) protocol is the industry standard for electronic communications with the exchange from the private server for direct market access (DMA) to real-time information. C++ is the common choice of programming language for trading over the FIX protocol, though other languages, such as .NET framework common language and Java can be used. Before creating an algorithmic trading platform, you would need to assess various factors, such as speed and ease of learning before deciding on a specific language for the purpose.
Brokerage firms would provide a trading platform of some sort to their customers for them to execute orders on selected exchanges in return for the commission fees. Some brokerage firms may offer an API as part of their service offering to technically inclined customers who wish to run their own trading algorithms. In most circumstances, customers may also choose from a number of commercial trading platforms offered by third-party vendors. Some of these trading platforms may also offer API access to route orders electronically to the exchange. It is important to read the API documentation beforehand to understand the technical capabilities offered by your broker and to formulate an approach in developing an algorithmic trading system.
The following table lists some brokers and trading platform vendors who have their API documentation publicly available:
Broker/vendor | URL | Programming languages supported |
---|---|---|
Interactive Brokers
|
https://www.interactivebrokers.com/en/index.php?f=1325
|
C++, Posix C++, Java, and Visual Basic for ActiveX
|
E*Trade
|
|
Java, PHP, and C++
|
IG
|
|
REST, Java, FIX, and Microsoft .NET Framework 4.0
|
Tradier
|
|
Java, Perl, Python, and Ruby
|
TradeKing
|
https://developers.tradeking.com
|
Java, Node.js, PHP, R, and Ruby
|
Cunningham trading systems
|
http://www.ctsfutures.com/wiki/T4%20API%2040.MainPage.ashx
|
Microsoft .NET Framework 4.0
|
CQG
|
http://cqg.com/Products/CQG-API.aspx
|
C#, C++, Excel, MATLAB, and VB.NET
|
Trading technologies
|
https://developer.tradingtechnologies.com
|
Microsoft .NET Framework 4.0
|
OANDA
|
|
REST, Java, FIX, and MT4
|
With many choices of programming languages available to interface with brokers or vendors, the question that comes naturally to anyone starting out in algorithmic trading platform development is: which language should I use?
Well, the short answer is that there is really no best programming language. How your product will be developed, the performance metrics to follow, the costs involved, latency threshold, risk measures, and the expected user interface are pieces of the puzzle to be taken into consideration. The risk manager, execution engine, and portfolio optimizer are some major components that will affect the design of your system. Your existing trading infrastructure, choice of operating system, programming language compiler capability, and available software tools poses further constraints on the system design, development, and deployment.
It is important to define the outcomes of your trading system. An outcome could be a research-based system that might be more concerned with obtaining high-quality data from data vendors, performing computations or running models, and evaluating a strategy through signal generation. Part of the research component might include a data-cleaning module or a backtesting interface to run a strategy with theoretical parameters over historical data. The CPU speed, memory size, and bandwidth are factors to be considered while designing our system.
Another outcome could be an execution-based system that is more concerned with risk management and order handling features to ensure timely execution of multiple orders. The system must be highly robust and handle any point of failure during the order execution. As such, network configuration, hardware, memory management and speed, and user experience are some factors to be considered when designing a system in executing orders.
A system may contain one or more of these functionalities. Designing larger systems inevitably add complexity to the framework. It is recommended that you choose one or more programming languages that can address and balance the development speed, ease of development, scalability, and reliability of your trading system.
In this section, we will build a working algorithmic trading platform that will authenticate with Interactive Brokers (IB) and log in, retrieve the market data, and send orders. IB is one of the most popular brokers in the trading community and has a long history of API development. There are plenty of articles on the use of the API available on the Web. IB serves clients ranging from hedge funds to retail traders. Although the API does not support Python directly, Python wrappers such as IbPy are available to make the API calls to the IB interface. The IB API is unique to its own implementation, and every broker has its own API handling methods. Nevertheless, the documents and sample applications provided by your broker would demonstrate the core functionality of every API interface that can be easily integrated into an algorithmic trading system if designed properly.
The official page for IB is https://www.interactivebrokers.com. Here, you can find a wealth of information regarding trading and investing for retail and institutional traders. In this section, we will take a look at how to get the Trader WorkStation X (TWS) installed and running on your local workstation before setting up an algorithmic trading system using Python. Note that we will perform simulated trading on a demonstration account. If your trading strategy turns out to be profitable, head to the OPEN AN ACCOUNT section of the IB website to open a live trading account. Rules, regulations, market data fees, exchange fees, commissions, and other conditions are subjected to the broker of your choice. In addition, market conditions are vastly different from the simulated environment. You are encouraged to perform extensive testing on your algorithmic trading system before running on live markets.
The following key steps describe how to install TWS on your local workstation, log in to the demonstration account, and set it up for API use:
IbPy is an add-on module for Python that wraps the IB API. It is open source and can be found at https://github.com/blampe/IbPy. Head to this URL and download the source files. Unzip the source folder, and use Terminal to navigate to this directory. Type python setup.py install to install IbPy as part of the Python runtime environment.
The use of IbPy is similar to the API calls, as documented on the IB website. The documentation for IbPy is at https://code.google.com/p/ibpy/w/list.
In this section, we will start interacting with TWS using Python by establishing a connection and sending out a market order to the exchange.
Once IbPy is installed, import the following necessary modules into our Python script:
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection
Next, implement the logging functions to handle calls from the server. The error_handler method is invoked whenever the API encounters an error, which is accompanied with a message. The server_handler method is dedicated to handle all the other forms of returned API messages. The msg variable is a type of an ib.opt.message object and references the method calls, as defined by the IB API EWrapper methods. The API documentation can be accessed at https://www.interactivebrokers.com/en/software/api/api.htm. The following is the Python code for the server_handler method:
def error_handler(msg):
print "Server Error:", msg
def server_handler(msg):
print "Server Msg:", msg.typeName, "-", msg
We will place a sample order of the stock AAPL. The contract specifications of the order are defined by the Contract class object found in the ib.ext.Contract module. We will create a method called create_contract that returns a new instance of this object:
def create_contract(symbol, sec_type, exch, prim_exch, curr):
contract = Contract()
contract.m_symbol = symbol
contract.m_secType = sec_type
contract.m_exchange = exch
contract.m_primaryExch = prim_exch
contract.m_currency = curr
return contract
The Order class object is used to place an order with TWS. Let's define a method called create_order that will return a new instance of the object:
def create_order(order_type, quantity, action):
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
After the required methods are created, we can then begin to script the main functionality. Let's initialize the required variables:
if __name__ == "__main__":
client_id = 100
order_id = 1
port = 7496
tws_conn = None
Note that the client_id variable is our assigned integer that identifies the instance of the client communicating with TWS. The order_id variable is our assigned integer that identifies the order queue number sent to TWS. Each new order requires this value to be incremented sequentially. The port number has the same value as defined in our API settings of TWS earlier. The tws_conn variable holds the connection value to TWS. Let's initialize this variable with an empty value for now.
Let's use a try block that encapsulates the Connection.create method to handle the socket connections to TWS in a graceful manner:
try:
# Establish connection to TWS.
tws_conn = Connection.create(port=port,
clientId=client_id)
tws_conn.connect()
# Assign error handling function.
tws_conn.register(error_handler, 'Error')
# Assign server messages handling function.
tws_conn.registerAll(server_handler)
finally:
# Disconnect from TWS
if tws_conn is not None:
tws_conn.disconnect()
The port and clientId parameter fields define this connection. After the connection instance is created, the connect method will try to connect to TWS.
When the connection to TWS has successfully opened, it is time to register listeners to receive notifications from the server. The register method associates a function handler to a particular event. The registerAll method associates a handler to all the messages generated. This is where the error_handler and server_handler methods declared earlier will be used for this occasion.
Before sending our very first order of 100 shares of AAPL to the exchange, we will call the create_contract method to create a new contract object for AAPL. Then, we will call the create_order method to create a new Order object, to go long 100 shares. Finally, we will call the placeOrder method of the Connection class to send out this order to TWS:
# Create a contract for AAPL stock using SMART order routing.
aapl_contract = create_contract('AAPL',
'STK',
'SMART',
'SMART',
'USD')
# Go long 100 shares of AAPL
aapl_order = create_order('MKT', 100, 'BUY')
# Place order on IB TWS.
tws_conn.placeOrder(order_id, aapl_contract, aapl_order)
That's it! Let's run our Python script. We should get a similar output as follows:
Server Error: <error id=-1, errorCode=2104, errorMsg=Market data farm
connection is OK:ibdemo>
Server Response: error, <error id=-1, errorCode=2104, errorMsg=Market
data farm connection is OK:ibdemo>
Server Version: 75
TWS Time at connection:20141210 23:14:17 CST
Server Msg: managedAccounts - <managedAccounts accountsList=DU15200>
Server Msg: nextValidId - <nextValidId orderId=1>
Server Error: <error id=-1, errorCode=2104, errorMsg=Market data farm
connection is OK:ibdemo>
Server Msg: error - <error id=-1, errorCode=2104, errorMsg=Market data
farm connection is OK:ibdemo>
Server Error: <error id=-1, errorCode=2107, errorMsg=HMDS data farm
connection is inactive but should be available upon demand.demohmds>
Server Msg: error - <error id=-1, errorCode=2107, errorMsg=HMDS data farm
connection is inactive but should be available upon demand.demohmds>
Basically, what the error messages say is that there are no errors and the connections are OK. Should the simulated order be executed successfully during market trading hours, the trade will be reflected in TWS:
The full source code of our implementation is given as follows:
""" A Simple Order Routing Mechanism """
from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection
def error_handler(msg):
print "Server Error:", msg
def server_handler(msg):
print "Server Msg:", msg.typeName, "-", msg
def create_contract(symbol, sec_type, exch, prim_exch, curr):
contract = Contract()
contract.m_symbol = symbol
contract.m_secType = sec_type
contract.m_exchange = exch
contract.m_primaryExch = prim_exch
contract.m_currency = curr
return contract
def create_order(order_type, quantity, action):
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
return order
if __name__ == "__main__":
client_id = 1
order_id = 119
port = 7496
tws_conn = None
try:
# Establish connection to TWS.
tws_conn = Connection.create(port=port,
clientId=client_id)
tws_conn.connect()
# Assign error handling function.
tws_conn.register(error_handler, 'Error')
# Assign server messages handling function.
tws_conn.registerAll(server_handler)
# Create AAPL contract and send order
aapl_contract = create_contract('AAPL',
'STK',
'SMART',
'SMART',
'USD')
# Go long 100 shares of AAPL
aapl_order = create_order('MKT', 100, 'BUY')
# Place order on IB TWS.
tws_conn.placeOrder(order_id, aapl_contract, aapl_order)
finally:
# Disconnect from TWS
if tws_conn is not None:
tws_conn.disconnect()
In this article, we were introduced to the evolution of trading from the pits to the electronic trading platform, and learned how algorithmic trading came about. We looked at some brokers offering API access to their trading service offering. To help us get started on our journey in developing an algorithmic trading system, we used the TWS of IB and the IbPy Python module.
In our first trading program, we successfully sent an order to our broker through the TWS API using a demonstration account.