发送和接收消息¶
介绍 ¶
本文作为使用FIX API与Spotware cServer交互的入门指南,适用于所有对使用FIX与cServer交互感兴趣的人。
在本文中,我们将使用C#示例详细描述如何构建FIX消息、将其发送到服务器并接收响应的原理。 这个示例绝不是一个完美无缺的应用程序,而是尽可能保持简单,以便程序员能够轻松理解使用FIX API消息的概念。
为了与服务器建立和维护适当的通信以及正确处理响应,还需要额外的功能,为了简单和清晰起见,这些功能在此被省略了。我们将在未来的文章中讨论这些主题。
代码示例 ¶
您可以在我们的GitHub仓库中找到本文讨论的代码示例
FIX通信概述 ¶
FIX消息只是一个由数字标签和值组成的字符串,用竖线(|)分隔。每个标签代表一个不同的字段,允许使用一组特定的值。下面您可以看到一个请求服务器进行身份验证的FIX消息示例。
8=FIX.4.4|9=126|35=A|49=theBroker.12345|56=CSERVER|34=1|52=20170117- 08:03:04|57=TRADE|50=any_string|98=0|108=30|141=Y|553=12345|554=passw0rd!|10=131|
如您所见,每个FIX消息中都可以找到的重复模式是:
Tag=Value|Tag=Value|Tag=Value|...
根据每条消息的目的,每次都需要不同的标签和值集。每条消息所需的标签和值在cTrader FIX引擎交互规则中有详细描述(请务必查看最新的交互规则)。
同样,服务器也会以类似的方式发送回响应。下面您可以看到服务器对上述消息的响应。
8=FIX.4.4|9=106|35=A|34=1|49=CSERVER|50=TRADE|52=20170117- 08:03:04.509|56=theBroker.12345|57=any_string|98=0|108=30|141=Y|10=066|
与FIX服务器通信过程中涉及的步骤如下:
-
构建FIX消息
-
传输FIX消息
-
接收FIX消息
-
解析FIX消息
原始FIX消息并不是一种非常易读的格式,因为它的设计考虑的是效率而不是可理解性。 因此,对于每个软件应用程序,都需要一个将提供的信息转换为相应FIX消息的过程。
在我们的C#示例应用程序中,我们创建了一个用于处理消息构建的类,以及基于相关信息创建FIX消息的函数。
消息构建完成后,它们通过网络套接字在服务器和客户端之间通过互联网传输。接收到消息后,需要对其进行解析以便以可读格式呈现。
在本文中,我们将介绍构建、传输和接收回复的过程。我们将在未来的文章中讨论解析。
构建FIX消息 ¶
消息结构 ¶
在我们的示例应用程序中,我们创建了一个负责创建FIX消息的类。该类名为MessageConstructor,可以在FIX API Library项目中找到。
MessageConstructor使用以下参数进行初始化:
-
Host(*)– 我们的cServer所在的地址。 -
Username(*)– 账号 -
Password(*)– 密码 -
SenderCompID(*)– 在cTrader的FIX API表单中提供。格式为 -
SenderSubID*– 是SenderCompID的第二部分 -
TargetCompID(*)– 在cTrader的FIX API表单中提供(通常是cServer)
您可以在cTrader FIX API表单中找到这些信息。
初始化MessageConstructor后,我们就可以构建FIX API消息了。
所有消息的构建方式都类似。下面是构建登录消息的代码示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
您可以看到,我们首先构建主体部分,然后将其传递给头部函数,最后将两部分都传递给尾部函数。这三个部分将在下面详细介绍。
消息构建过程只是将所需的标签、值和分隔符添加到字符串中。
主体 ¶
我们首先从描述主体构建开始,因为需要先创建消息的主体。我们可以在上面看到一个示例(创建登录消息)。
我们首先初始化一个StringBuilder类,然后根据函数输入逐个附加标签。根据消息类型,主体必须由不同的标签集组成,其中一些是必需的,另一些是可选的。
您可以在我们的交互规则(/FIX)中找到每条消息的结构。
然后我们为登录消息创建一个头部,并将消息的主体附加到其中。最后,使用headerAndBody字符串生成尾部。接下来,我们将看到如何构建头部和尾部。
头部 ¶
头部是FIX消息的第一部分,由以下字段组成(所有消息都相同):
BeginString– 开始字符串定义FIX协议版本,在我们的情况下固定为FIX4.4。BodyLength– 主体长度表示消息的字符长度,不包括BeginString、BodyLength和尾部字段。MsgType– 在此字段中我们定义消息类型,以便接收方知道如何解析主体。SenderCompID– 在这里我们设置SenderCompID。TargetCompID– 这是我们消息的目标。在我们的情况下,它始终是cServer。SenderSubID– 交易者登录。MsgSeqNum– 这是消息的序列号。在同一会话中发送的每条消息都需要增加。Sending Time– 消息传输时间。
下面您可以看到负责构建头部的ConstructHeader函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | |
尾部 ¶
尾部只是一个包含消息其余部分校验和的标签。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
系统消息 ¶
我们的示例包含返回以下系统消息的函数:
- 心跳:
MessageConstructor.HeartbeatMessage() - 测试请求:
MessageConstructor.TestRequestMessage() - 登录:
MessageConstructor.LogonMessage() - 登出:
MessageConstructor.LogoutMessage() - 重发请求:
MessageConstructor.ResendMessage() - 拒绝:
MessageConstructor.RejectMessage() - 序列重置:
MessageConstructor.SequenceResetMessage()
应用程序消息 ¶
我们的示例包含返回以下系统消息的函数:
- 市场数据请求:
MessageConstructor.HeartbeatMessage() - 市场数据快照/完整刷新:
MessageConstructor.MarketDataSnapshotMessage() - 市场数据增量刷新:
MessageConstructor.MarketDataIncrementalRefreshMessage() - 新单:
MessageConstructor.NewOrderSingleMessage() - 订单状态请求:
MessageConstructor.OrderStatusRequest() - 执行报告:
MessageConstructor.ExecutionReport() - 业务消息拒绝:
MessageConstructor.BusinessMessageReject() - 持仓请求:
MessageConstructor.RequestForPositions() - 持仓报告:
MessageConstructor.PositionReport()
发送消息并接收响应 ¶
为了向cServer发送FIX消息,您首先需要与服务器建立连接。您可以通过创建TcpClient来实现这一点。在我们的情况下,我们创建了两个客户端,因为价格报价消息和交易消息由服务器上的不同端口处理。
然后,我们需要获取将发送消息的两个流。这个过程在表单的构造函数中进行,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
在构造函数中,我们还初始化了一个MessageConstructor类,用于生成消息。
接下来,为了发送消息,我们创建了两个不同的函数,SendPriceMessage()和SendTradeMessage()。每个函数都将FIX消息作为输入,然后调用SendMessage()函数,将消息和相应的流作为输入。
SendMessage()函数的工作原理如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | |
详细步骤如下:
- 将消息编码为字节数组。
- 将字节数组写入流。
- 从流中读取回复。
- 增加消息序列号。
- 将消息编码为字符串。
该函数应返回服务器发送的FIX消息。
正如您所假设的,您不能向用户显示原始FIX消息,因此还应开发一个额外的步骤来解析传入的消息。
结论 ¶
这个应用程序简要演示了如何使用FIX消息与cServer通信。它只是一个说明FIX协议概念的示例,绝不是一个完整的FIX引擎。如果您想避免构建自己的FIX引擎,可以考虑使用可用的第三方FIX引擎之一。
注意
本文截至2017年2月3日是最新的,并考虑了cTrader FIX引擎交互规则v2.9.1。