4

I'm writting a FIX Engine based on Quickfix/N that listen for trade Executions (ExecutionReport) and save them into a database.

Requesting a field value from the API throws a FieldNotFoundException if the value is not present in the received message. By example calling executionReport.Account will throw the exception if the account is not present.

As some fields are optional, I have to explicitely check for the existence of the field value before getting it. I have two possibilities for that:

Possibility 1: executionReport.IsSetAccount() ? executionReport.Account : null;

Possibility 2:

  try
        {
            return executionReport.Account.getValue();
        }
        catch (Exception e)
        {
            return null;

        }

The first option is clean but I find it really heavy, the second can be generalized into an helper function but It goes against the API philosophy and I have the feeling I do something wrong.

Then my question is:

  • Is there another clean/correct way to do the job?
  • Or is my comprehension of the Protocol/API totally wrong ? I have the feeling I don't get the problem in the right way.

    Thanks a lot

Fede
  • 804
  • 1
  • 10
  • 21
  • I think you get the problem - some fields are optional. Well that's a feature of the FIX protocol. It's the same for nearly every FIX message. There are a lot of different ways of transacting... – rupweb Oct 14 '17 at 10:04

2 Answers2

5

You haven't really stated why you think those are unclean, so I'm not sure what exactly you're looking for.

The only alternative I can think of is this:

// Both these lines are functionally identical.
executionReport.IsSetField(1)
executionReport.IsSetField(QuickFix.Fields.Tags.Account)

// 1 is the tag for Account.
// The second line just uses the tag enum to get 1
//   instead of hardcoding the int.

Is that better?

Grant Birchmeier
  • 17,809
  • 11
  • 63
  • 98
  • Yes it's an alternative, it gives the advantage to generalize the validatoion. But as it's mentioned in the API documentation it needs extra boilrplate logic and is not recommended because is less type safe. – Fede Oct 12 '17 at 09:30
  • I won't say the 2 options are not clean, they both do the job and in anycase I don't have choice to adapt the ExecutionReport entity provided by the API. But this is the point, the API force me to explecitly check the fields before to do the get. Then my second option goes against this contract. The first option is fine and "clean", but it's really heavy as there are undreds of fields. Is like having a DTO with hundreds of getters and check explicitely everytime I call a getter. – Fede Oct 12 '17 at 09:41
  • Well, I don't think there a cleaner solution. The fields are optional, and you can't get a value that isn't there, so you are forced to check its presence. There's no way around it. – Grant Birchmeier Oct 12 '17 at 15:45
  • I agree, Just was curious about how Quickfix users do the job. – Fede Oct 13 '17 at 10:36
1

Ok, to avoid having to write an adapter class or do may check everytime I want to use an ExecutionReport field, I created an extension class that do the job:

    public static class ExecutionReportExtensions
{
    public static string AccountValue(this QuickFix.FIX44.ExecutionReport executionReport)
    {
        if (executionReport.IsSetAccount())
            return executionReport.Account.getValue();
        return null;
    }

And then use it as follow:

executexecutionReport.AccountValue()

Fede
  • 804
  • 1
  • 10
  • 21