Python Sample for the Ember FIX API
This sample explains how to run a simple Python client that sends trading orders to the Deltix FIX Gateway using the popular QuickFIX/Python library.
Pre-requisites
Before you can run the sample, ensure you have the following pre-requisites in place:
Install Python 3.7+ and pip on your system using the following command:
sudo yum install python3-devel python3-wheel
Install the QuickFIX Python library using the following pip command:
pip3 install quickfix
For Windows users facing any problems with this step, you can get QuickFIX binaries here.
Set up the Deltix FIX Gateway.
Download the source code of this sample from GitHub.
Configure
To use the Python client with your specific Ember configuration, modify the fix-client.cfg file as follows:
- Point the
SocketConnectHost
andSocketConnectPort
properties to your Deltix FIX Gateway. These properties define the host and port to which the client will connect. - Make sure
SenderCompID
,TargetCompID
, andSenderPassword
match the credentials of the FIX Session you want to connect as. - (Optional) If you need to specify custom file paths for storing messages and logs, update
FileStorePath
andFileLogPath
. By default, the client uses the current working directory.
Run
To run the sample client, execute fix-client.py
with fix-client.cfg
as a parameter on Python 3.x:
python3 fix-client.py fix-client.cfg
If client successfully connects, it will display a message about the successful login and then show the following command prompt:
Session FIX.4.4:TCLIENT1->DELTIX successfully logged in
Received message: MessageType=News, Sender=DELTIX, HeadLine=Connector Status, Text=SIM:CONNECTED
-->
Sending Trading Orders
At this point, you can enter commands to issue BUY or SELL orders with specified parameters and time interval. The client will display any application messages (order events) received from the FIX server.
To view supported commands and parameters type help
:
--> help
usage: help | exit | {buy,sell} -s SYMBOL -q QUANTITY [-t {LIMIT,MARKET}] [-p PRICE] [-d DESTINATION] [-e EXCHANGE] [-n ORDER_COUNT] [-i INTERVAL]
Example
In the example above, the last two parameters, ORDER_COUNT
(default is 1) and INTERVAL
(default is 5 seconds), are used to issue multiple orders with the specified time interval (in seconds) between orders.
To issue 10 LIMIT BUY orders to the SOR algorithm, buying 1 BTCUSD coin every 15 seconds, with a limit price of 8081, the command would look like this:
--> buy -s BTCUSD -q 1 -t LIMIT -p 8081 -d SOR -n 10 -i 15
In this example, the options set the following FIX tags on the order request:
-s – fix.Symbol
-t - fix.OrdType
-q - fix.OrderQty
-p - fix.Price
-d - fix.ExecBroker (ember destination, this could be simulator, matching engine, execution algo, or exchange connector)
-e - fix.ExDestination (identifies exchange)
QuickFIX API
QuickFIX provides the quickfix.Application
class, which has notification methods called whenever the client sends or receives messages from the FIX server. To use QuickFIX, you should extend this class and override its notification methods. For an example, see the provided fix-client.py.
Overriding the toAdmin()
Method
To supply the server with the password during login, you can override the toAdmin()
method and add the password to the header of the FIX Logon message:
Here's an example:
def toAdmin(self, message, sessionID):
msgType = fix.MsgType();
message.getHeader().getField(msgType)
if msgType.getValue() == fix.MsgType_Logon :
message.getHeader().setField(fix.Password(self.sessionPwd))
return
Overriding the fromApp()
Method
To handle FIX server execution report messages, override the fromApp()
method in your application:
def fromApp(self, message, sessionID):
print("Received message: ", end='')
print_message(message)
return
Initializing the Client Session
To initialize the client session, pass an instance of your Application class to SocketInitiator
along with the configuration settings, and then start it like this:
settings = quickfix.SessionSettings(config_file)
store_factory = quickfix.FileStoreFactory(settings)
log_factory = quickfix.FileLogFactory(settings)
application = Application()
initiator = quickfix.SocketInitiator(application, store_factory, settings, log_factory)
initiator.start()
Sending Order Requests
Once the SocketInitiator
is started, and the session is initialized, the client can send order requests using the quickfix.Session.sendToTarget()
method.
Here is a sample code that sends a LIMIT BUY order to the SIM algorithm:
trade = fix.Message()
trade.getHeader().setField(fix.BeginString(fix.BeginString_FIX44))
trade.getHeader().setField(fix.MsgType(fix.MsgType_NewOrderSingle))
trade.setField(fix.ClOrdID("1121212"))
trade.setField(fix.HandlInst(fix.HandlInst_MANUAL_ORDER_BEST_EXECUTION))
trade.setField(fix.TimeInForce(fix.TimeInForce_DAY))
trade.setField(fix.Symbol("BTCUSD"))
trade.setField(fix.Side(fix.Side_BUY))
trade.setField(fix.OrdType(fix.OrdType_LIMIT))
trade.setField(fix.OrderQty(2))
trade.setField(fix.Price(8081))
trade.setField(fix.TransactTime())
trade.setField(fix.ExecBroker("SIM"))
fix.Session.sendToTarget(trade, self.sessionID)
In this code snippet, the trade
message is constructed and then sent to the target using the sendToTarget()
method of the Session
class.