如何针对不同交易所定制QuickFIX C++中的字段类型?
如何针对不同交易所定制QuickFIX C++中的字段类型?
这个问题我之前帮不少开发者解决过,QuickFIX默认的全局字段定义逻辑确实是多交易所定制时的常见痛点。结合你的场景(比如ClOrdID被定义为INT而非标准STRING),给你几个实用的解决方案,按推荐程度排序:
1. 给每个交易所的定制协议独立生成命名空间隔离的代码
这是最稳妥、最符合C++类型安全原则的方案,核心思路是把每个交易所的定制FIX协议当成独立的“版本”来处理,用命名空间隔离不同的字段类型定义。
具体操作步骤:
- 为每个交易所复制一份你修改好的
FIX42.xml,比如重命名为FIX42_MYEXCHANGE.xml、FIX42_ANOTHEREXCHANGE.xml - 修改代码生成脚本(
generate.sh),针对每个定制XML文件,生成代码时指定独立的命名空间和输出目录。比如给FIX42_MYEXCHANGE.xml生成的代码全部包裹在FIX42_MYEXCHANGE命名空间下,输出到src/fix42_myexchange目录 - 生成完成后,每个交易所的字段类型会完全隔离:比如
FIX42_MYEXCHANGE::ClOrdID是INT类型,而标准FIX42::ClOrdID还是STRING类型,不会有全局冲突 - 在业务代码里,针对不同交易所的连接,直接使用对应命名空间的字段和消息类即可,比如:
// 处理定制交易所的消息 FIX42_MYEXCHANGE::NewOrderSingle order; FIX42_MYEXCHANGE::ClOrdID clOrdID(123456); order.set(clOrdID); // 处理标准FIX42的消息 FIX42::NewOrderSingle standardOrder; FIX42::ClOrdID standardClOrdID("ABC789"); standardOrder.set(standardClOrdID);
2. 单交易所场景下:修改代码生成模板或手动固定字段类型
如果你的系统只需要支持这一个定制交易所,不需要兼容标准FIX或其他交易所,可以用这个更简单的方法:
- 找到QuickFIX代码生成器的模板文件(比如
field.h、field.cpp的模板,通常在QuickFIX的generator/templates目录下) - 修改模板中字段类型的生成逻辑,或者直接在你修改后的
FIX42.xml里确保字段类型被正确定义为INT - 生成代码后,把
FixFields.h等核心文件备份好,避免后续重新生成代码时被覆盖;或者修改generate.sh脚本,在生成后自动应用你的定制修改(比如用sed替换字段类型)
这种方法的缺点是扩展性差,后续要加其他交易所的话会很麻烦,但胜在简单直接。
3. 动态字段处理:绕过强类型字段定义(临时 workaround)
如果不想修改生成代码,或者只需要处理个别字段的类型差异,可以用QuickFIX提供的动态字段API,绕过自动生成的强类型字段类:
- 设置字段时,直接用
Message::setField的动态重载版本,手动传入标签和对应类型的值:FIX42::NewOrderSingle order; // 直接传入INT类型的ClOrdID值,不用生成的ClOrdID类 order.setField(11, 123456); - 解析字段时,同样用动态方法获取对应类型的值:
int clOrdIDValue; order.getField(11, clOrdIDValue);
这种方法的优点是灵活,不用修改任何生成代码,但缺点是失去了强类型的编译期检查,容易出现标签号写错、类型不匹配的问题,适合临时适配个别字段,不建议大规模使用。
注意事项
- 用命名空间隔离的方案时,要确保每个交易所的消息会话(Session)对应使用正确命名空间的消息类,避免跨命名空间混用导致的类型错误
- 无论用哪种方法,都要在测试环境中充分验证字段的序列化和反序列化,确保和交易所的协议完全匹配,比如INT类型的ClOrdID会不会被序列化为数字字符串,符合交易所的要求
内容来源于stack exchange
相关产品推荐
相关产品推荐

