Per out previous discussion on execution report implementation I tried the quickfix github documentation. I was hoping if you have a moment you might be able to assist me in bridging the provided acceptor with an active fix session that I am connected to.
I am trying to implement executor.py to provide execution report details for orders I am passing to the exchange and market data requests. I have a successful session connection with the exchange on a UAT session. I place an order successfully and run python executor.py executor.cfg in a seperate terminal to try to capture the return message but nothing happens:
U:\quickfix-python-samples\initiator>python executor.py executor.cfg
<20210520-15:07:49.000000000, FIX.4.2:KWESTFUT42->WELLSFUT42, event>
(Created session)
This is my config file:
[DEFAULT]
DefaultApplVerID=FIX.4.2
FileStorePath=./Sessions/
ConnectionType=acceptor
StartTime=00:00:00
EndTime=00:00:00
ReconnectInterval=5
ValidOrderTypes=1,2,F
SenderCompID=******
TargetCompID=******
UseDataDictionary=Y
DefaultMarketPrice=12.30
[SESSION]
BeginString=FIX.4.2
SocketAcceptPort=9000
DataDictionary=./spec/FIX42.xml
FileLogPath=./Logs/
FileStorePath=./Sessions/
SenderCompID=******
TargetCompID=******
DeliverToCompID=******
HeartBtInt=30
SocketConnectPort=******
SocketConnectHost=******
executor.py:
import sys
import time
import quickfix as fix
class Application(fix.Application):
orderID = 0
execID = 0
def onCreate(self, sessionID): return
def onLogon(self, sessionID): return
def onLogout(self, sessionID): return
def toAdmin(self, sessionID, message): return
def fromAdmin(self, sessionID, message): return
def toApp(self, sessionID, message): return
def fromApp(self, message, sessionID):
beginString = fix.BeginString()
msgType = fix.MsgType()
message.getHeader().getField( beginString )
message.getHeader().getField( msgType )
symbol = fix.Symbol()
side = fix.Side()
ordType = fix.OrdType()
orderQty = fix.OrderQty()
price = fix.Price()
clOrdID = fix.ClOrdID()
message.getField( ordType )
if ordType.getValue() != fix.OrdType_LIMIT:
raise fix.IncorrectTagValue( ordType.getField() )
message.getField( symbol )
message.getField( side )
message.getField( orderQty )
message.getField( price )
message.getField( clOrdID )
executionReport = fix.Message()
executionReport.getHeader().setField( beginString )
executionReport.getHeader().setField( fix.MsgType(fix.MsgType_ExecutionReport) )
executionReport.setField( fix.OrderID(self.genOrderID()) )
executionReport.setField( fix.ExecID(self.genExecID()) )
executionReport.setField( fix.OrdStatus(fix.OrdStatus_FILLED) )
executionReport.setField( symbol )
executionReport.setField( side )
executionReport.setField( fix.CumQty(orderQty.getValue()) )
executionReport.setField( fix.AvgPx(price.getValue()) )
executionReport.setField( fix.LastShares(orderQty.getValue()) )
executionReport.setField( fix.LastPx(price.getValue()) )
executionReport.setField( clOrdID )
executionReport.setField( orderQty )
if beginString.getValue() == fix.BeginString_FIX40 or beginString.getValue() == fix.BeginString_FIX41 or beginString.getValue() == fix.BeginString_FIX42:
executionReport.setField( fix.ExecTransType(fix.ExecTransType_NEW) )
if beginString.getValue() >= fix.BeginString_FIX41:
executionReport.setField( fix.ExecType(fix.ExecType_FILL) )
executionReport.setField( fix.LeavesQty(0) )
try:
fix.Session.sendToTarget( executionReport, sessionID )
except fix.SessionNotFound as e:
return
def genOrderID(self):
self.orderID = self.orderID+1
return self.orderID
def genExecID(self):
self.execID = self.execID+1
return self.execID
try:
file = sys.argv[1]
settings = fix.SessionSettings( file )
application = Application()
storeFactory = fix.FileStoreFactory( settings )
logFactory = fix.ScreenLogFactory( settings )
acceptor = fix.SocketAcceptor( application, storeFactory, settings, logFactory )
acceptor.start()
except (fix.ConfigError, fix.RuntimeError) as e:
print(e)
Can you assist me in implementing a successful execution report to pair with my client?
I am attaching the code for the client here:
#!/usr/bin/env python
import configparser
import logging
from time import sleep
import click
from modules.client import (Client, delete_order, fix, new_order,
replace_order, send)
from modules.utils import setup_logging
@click.command(
context_settings=dict(help_option_names=["-h", "--help"]),
options_metavar="[options...]",
)
@click.argument(
"client_config", type=click.Path(exists=True), metavar="[client config]"
)
@click.option(
"-d",
"--debug",
is_flag=True,
default=False,
show_default=True,
help="Print debug messages.",
)
def main(client_config="configs/client1.cfg", debug=None):
"""FIX client
Sends new order over a FIX session.
"""
if debug:
logger.setLevel(logging.DEBUG)
logger.info(f"Logging set to debug.")
else:
logger.setLevel(logging.INFO)
logger.info(f"Logging set to info.")
config = configparser.ConfigParser()
config.read(client_config)
sender_compid = config["SESSION"]["SenderCompID"]
target_compid = config["SESSION"]["TargetCompID"]
settings = fix.SessionSettings(client_config)
store = fix.FileStoreFactory(settings)
app = Client()
app.set_logging(logger)
initiator = fix.SocketInitiator(app, store, settings)
initiator.start()
sleep(1)
while True:
try:
sleep(1)
choice = int(
input(
"Enter choice :- "
"\n1. New order"
"\n2. Replace order"
"\n3. Delete order"
"\n> "
)
)
if choice == 1:
print("Enter order :- ")
symbol = input("Symbol: ")
price = input("Price: ")
quantity = input("Quantity: ")
side = input("Side: ")
order_type = input("Type: ")
message = new_order(
sender_compid,
target_compid,
symbol,
quantity,
price,
side,
order_type,
)
print("Sending new order...")
send(message)
elif choice == 2:
order_id = input("Enter OrderID: ")
price = input("Price: ")
quantity = input("Quantity: ")
message = replace_order(
sender_compid, target_compid, quantity, price, order_id
)
print("Sending replace order...")
send(message)
elif choice == 3:
order_id = input("Enter OrderID: ")
message = delete_order(sender_compid, target_compid, order_id)
print("Sending delete order...")
send(message)
except KeyboardInterrupt:
initiator.stop()
print("Goodbye... !\n")
if name == "main":
logger = setup_logging("logs/", "client")
main()