2017-10-11 84 views
0

我正在写一个基于Quickfix/N的FIX引擎,它侦听交易执行(ExecutionReport)并将它们保存到数据库中。QuickFix可选字段检查值存在

如果接收到的消息中不存在该值,则从API请求字段值将引发FieldNotFoundException。举例来说,如果帐户不存在,调用executionReport.Account将抛出异常。

由于有些字段是可选的,我必须在获取字段值之前明确检查字段值的存在。 我有两个可能性:

可能性1: executionReport.IsSetAccount() ? executionReport.Account : null;

可能性2:

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

     } 

第一个选项是干净的,但我觉得很沉重,第二个可以推广到帮助器功能,但它违背了API的哲学,我感觉我做错了什么。

然后我的问题是:

  • 有没有做这项工作的另一个清洁/正确的方法?
  • 或者是我对Protocol/API的理解完全错误? 我有这种感觉,我没有以正确的方式解决问题。

    非常感谢

+0

我想你会遇到这个问题 - 有些字段是可选的。那是FIX协议的一个特性。几乎每个FIX消息都是一样的。有很多不同的交易方式... – rupweb

回答

1

你真的没有说为什么你认为这些都是不洁的,所以我不知道正是你要寻找的。

我能想到的唯一的选择是这样的:

// 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. 

是不是更好?

+0

是的,它是一种替代方案,它有利于推广validatoion。但正如在API文档中提到的那样,它需要额外的boilrplate逻辑并且不推荐,因为类型安全性较低。 – Fede

+0

我不会说这2个选项不干净,它们都做这项工作,并且在任何情况下我都没有选择来修改API提供的ExecutionReport实体。但这是关键,API迫使我在执行此操作之前非常不情愿地检查字段。然后我的第二个选择违背了这个合同。第一种选择很好,而且“干净”,但由于有数百个区域,所以它非常重。就像拥有一个拥有数百名获得者的DTO,并且每次我打电话给一个获得者时都会明确地检查。 – Fede

+0

嗯,我不认为有一个更清洁的解决方案。这些字段是可选的,你不能得到一个不存在的值,所以你不得不检查它的存在。没有办法绕过它。 –

0

好,以避免写一个适配器类还是可以检查每次我想使用ExecutionReport场,我创建了一个扩展类来完成这项工作:

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

,然后用它作为跟随:

executexecutionReport.AccountValue()