5

Does QuickFIX provide the possibility of getting ALL existing fields of an incoming FIX message in a single step? (I use version 1.14.3 for Python.)

According to QuickFIX documentation, it's possible to get a field value in a certain way:

price = quickfix.Price()
field = message.getField(price)
field.getValue()

Various message types contain different fields, so doing that for every field would be awkward. What is more, sometimes it's unknown whether some fields exist in a message. How do I get all fields of a message not knowing what fields it contains?

Siega Oy
  • 51
  • 4
  • Why do you need to get all fields in a message ? Quickfix checks for the validity of a message i.e. check if required fields are present and then rejects/accepts it. Play with your config to do this, rather doing it in the code. If you want certain fields to be present mark them as mandatory and get your counterparty(ies) to agree with it. – DumbCoder Aug 17 '16 at 07:37
  • I want it because I need to receive many different kinds of FIX messages those might contain many different types of fields, so getting all fields in one scoop would be much easier than definig what fields I should get for every kind of message. That would take much time and make the code complicated for no good reason. – Siega Oy Aug 17 '16 at 08:37
  • `different kinds of FIX messages` What do you mean ? Different versions ? Or different FIX messages ? – DumbCoder Aug 17 '16 at 08:40
  • 1
    I mean different FIX messages such Execution report, Order Cancel Request, etc. – Siega Oy Aug 17 '16 at 09:02
  • OK it seems from your query you haven't used FIX much. Use your FIX xml config file for such details rather than trying to do it in your code. What you are trying to do is unnecessary and strictly not required. `Various message types contain different fields, so doing that for every field would be awkward` Is that you being lazy ? Yes you need to write handlers for messages(not fields, you extract them to use them)) and there is no way out of it. Or am I understanding your query incorrectly ?? – DumbCoder Aug 17 '16 at 09:12
  • I wouldn't say I'm lazy, I just don't want to write much code for no reason. I understand I need to write handlers for messages. For example, if I receive an MARKET DATA REQUEST REJECT(Y), that contains the MDReqRejReason field, then I need to get this value. And MARKET DATA SNAPSHOT/FULL REFRESH (W) doesn't have such value. – Siega Oy Aug 17 '16 at 10:30
  • So if I want to get all fields of different messages, I have to process messages like this: `msgType = message.getField(quickfix.MsgType()).getValue() if msgType == 'Y': MDReqRejReason = message.getField(quickfix.MDReqRejReason()).getValue() ...getting other fields specific for this type of messages elif msgType == 'W': ...getting fields specific for this type of messages elif msgType == '8': ...getting fields specific for this type of messages etc.` – Siega Oy Aug 17 '16 at 10:30
  • And if there were a method that would be able to return the values of all fields of the message, it would be enough to do something like this, no matter what type of message I process: allFields = message.getAllFields() So I guess I will have to write such method by myself. – Siega Oy Aug 17 '16 at 10:30

3 Answers3

0

I wasnt able to find a Quickfix API function for this either, but here is something straightforward which splits the raw message up by field separator 0x01 and then by '=':

for field in message.toString().split(chr(1)):
    field = field.split('=', 1)
    if len(field) == 2:
        print(f"{field[0]} = {field[1]}")

This prints something like:

8 = FIX.4.2
9 = 231
35 = 8
34 = 4
49 = Target
52 = 20220122-01:11:51.340
56 = 1234
17 = 9a1d510c-0cfa-43f6-9f6c-e713e5fb2954
20 = 0
37 = 5985669f-2dcf-46de-9f49-70a3a10e392e
38 = 0
39 = 3
54 = 1
55 = SPY
60 = 20220122-01:11:51.336
150 = 3
151 = 0
10 = 238
DanJ
  • 1,654
  • 1
  • 16
  • 23
-1

I'm not aware of a method. This is what I do, with message the incoming FIX message:

tags = re.findall(r'(?<=\x01).*?(?==)', str(message))

Then, where FIX = {'1':fix.Account(), '2':fix.AdvId(), ...}, you can get all values by doing

for tag in set(tags)&set(FIX.keys()):
    message.getField(FIX[tag])

Obviously you must import the re module.

Wapiti
  • 1,851
  • 2
  • 20
  • 40
-1

My way to parse FIX message:

tagd = {">>".join((str(n),x)):y for n,[x,y] in enumerate([b.split("=") for b in message.toString().split(chr(1)) if len(b)>1])}

Resulting in dict() with FIX code keys:

{'0>>8': 'FIX.4.4', '1>>9': '125', '2>>35': 'W', '3>>34': '3', '4>>49': 'CSERVER', '5>>50': 'QUOTE', '6>>52': '20200212-12:18:56.328', '7>>56': 'unique_string_id', '8>>55': '1', '9>>268': '2', '10>>269': '0', '11>>270': '1.08716', '12>>269': '1', '13>>270': '1.08718', '14>>10': '067'}

Enumeration is for repeated fields like 269 and 270. Cheers.