First, the definition
FIX protocol is an open protocol provided by the International Association FIX aim is to promote international trade electronically process between the various types of participants, including investment managers, brokers, buyers, sellers establish a real-time electronic communications protocol. FIX Protocol goal is to process all types of securities finance business needs formatting, making it a functional description of the processes available computer language, and unified exchange format on each business function interface for easy connection of each module.
Second, the agreement works
2.1 Communication model and the basic concepts
Communication model
-
Initiator: initiator, establishing the communication link, the session initiating party by sending an initial message Logon.
-
Acceptor: Receivers Receivers FIX session. Responsible for the implementation of the first level of certification and confirmed by an official statement transmitted messages Logon connection request is accepted.
-
Principles: the first is the initiator Initiator, the recipient is Acceptor.
- Standard mode gateway Acceptor, the client is frequently used as Initiator mode.
Fix connection
FIX connection consists of three parts: logon log, message exchange message transmission, logout cancellation.
- logon Log
- logout logout
Fix session
FIX session by one or more Connection FIX FIX connection components. A FIX session can have multiple logins.
serial number
-
FIX all messages by a unique label serial number. When the serial number of each session begins FIX is initialized to 1, and is incremented during the entire session. Monitoring session participants that the serial number may identify and handle lost messages, applications that can be quickly synchronized when reconnected in a FIX session.
- Each group received a session establishment and non-dependent transmission sequence. Session participants will send messages to maintain a given sequence and a sequence number gap monitoring message block accept message.
Heartbeat
-
During the message exchange, FIX application Heartbeat Heartbeat message is generated periodically. The heartbeat message may monitor communication link status and recognizes that the received sequence number space. Heartbeat periodic intervals transmitted by the session initiator used is defined in the message HeartBtInt Logon Domain.
- Heartbeat Heartbeat message time interval should be a message sent after every reset, i.e. after sending a message, no further messages sent Heartbeat sends a heartbeat message within a given time interval. Value HeartBtInt session the two sides should be recognized by a session by session initiation defined above the receiver confirmed by Logon messages. The two sides are the same HeartBtInt session - the originator and recipient login login common use.
Data Integrity Check
-
Integrity of the message data content can participate in two ways to verify: message length code check and efficacy.
-
BodyLength domain to the program by computing CheckSum flag ( "10 =") delimiter character number, message length fields marked BodyLength comparing efficacy complete integrity.
-
ChekSum integrity check, "8" Start, including binary and immediately be obtained comparing with the CheckSum CheckSum field delimiter mark each character from the domain "= 8" in by calculation.
- FIX message and a checksum is calculated with each byte message ChechSum domain (but not including) the. Then, the checksum is converted into digital mode and 256 for transmitting the comparison. Checksums are calculated after all cryptographic operations.
Verify Code:
样例:8=FIX.4.29=7335=A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y10=208
1、消息长度:9=73
35=A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y(这段长度)
2、效验码检查
char *GenerateCheckSum( char *buf, long bufLen ) {
static char tmpBuf[ 4 ]; long idx;
unsigned int cks;
for( idx = 0L, cks = 0; idx < bufLen; cks += (unsigned int)buf[ idx++ ] ); sprintf( tmpBuf, “%03d”, (unsigned int)( cks % 256 ) );
return( tmpBuf );
}
Message acknowledgment
-
FIX protocol does not support a single confirmation message. The method uses a time slot to monitor message and validation message recovery.
-
Normal data transfer (no single message acknowledgment) error message identified by the sequence gap. Each message is marked by a unique serial number. The receiver application is responsible for monitoring the received message to identify the message sequence number gap and generating a retransmission request.
-
Each participant FIX to FIX session must maintain two sequence numbers, a sequence number is received, is a transmission sequence number, both of which are initialized to 1 FIX to establish a session start. Each message is assigned a unique sequence number value, and incremented after sending the message. In addition, each received message has a unique serial number, the received sequence number counter is incremented upon receipt of each message.
- When correctly received sequence number and the sequence number need not be obtained a desired feature, error correction processing must be taken.
encryption
-
Encryption algorithm mutual agreement by the connection.
-
Any field of a message may be encrypted and placed SecureData domain. However, some display flag field must be transmitted in plain text. To ensure the integrity, plain text fields can be repeated in SecureData domain.
-
When encryption is recommended, but not required, all of the message body are encrypted. If part of the data set of data is repeated in a message to be encrypted, repeating the whole group must be encrypted.
- Good encryption algorithm pre-negotiated declared in Logon message.
Custom domain
-
FIX provide maximum flexibility to the user, FIX protocol allows user-defined fields. These fields between participants agree realization, application, and should be taken to avoid conflicts.
-
Tag numbers 5000-9999 are reserved for the user-defined fields. These tag values are used to exchange information Enterprise Alliance. FIX can register through the website.
- More than 10,000 reserved for internal use only a single enterprise. No registrations.
Third, message format
3.1 Data Types
Integer int, float float, a single character char, Boolean Boolean, String String, data DATA
3.2 Domain
Common Domain
Tag (tag) | FieldName (domain name) | Remark |
---|---|---|
8 | BeginString | Starting string, FIX protocol version |
9 | BodyLength | Message length |
35 | MsgType | Message type: for example, F = Order Cancel Request, cancel the order |
11 | ClOrdID | Client order ID |
37 | OrderID | Order ID server |
41 | OrigClOrdID | Original client order ID |
54 | Side | Business type. For example: 1 = Buy, 2 = Sell |
55 | Symbol | Stock code. For example: YRD |
10 | CheckSum | Check code |
Domain Syntax
-
It should be the beginning of a message header followed by the body, and finally the end of the message;
-
The order of the first three fields of the message header can not be changed: a starting sequence (Tag = 8), the length of the message body (Tag = 9), the message type (Tag = 35);
-
The last field of the message should be the end of the checksum field (Tag = 10);
-
Repeating groups, the order of the domains appear to follow the sequence of the repeating group definition message or component;
- In a message, in addition to any other domains outside repeating group can not be repeated.
Security and Encryption
-
Because of possible message on the public network transmission or switching insecure network, it is necessary to encrypt the sensitive data related processing.
-
Specific encryption method determined by the agreement reached between the parties connected.
-
In addition to the message identification fields need to expose certain outer expressly transmission to any other domain can be placed ciphertext encrypted data field (SecureData) inside. Of course, these fields may be encrypted plaintext representation of the retention time.
-
When deciding to use encryption scheme, can encrypt all fields within the message body. If encryption is required in some repeating group of message, then repeat the entire set of encryption required.
- Some fields of this Agreement also provides support for digital signatures, key exchange, and text encryption and other security technologies.
3.3 Message
Header
Each session or application message has a header, the header indicating the type of message, the length of the message body, the destination, the message number, a transmission starting point and the transmission time.
Tag | domain name | essential | Explanation |
---|---|---|---|
8 | BeginString | Y | Starting string values: FIX.4.2 (not encrypted, the first field of the message) |
9 | BodyLength | Y | Length of body (non-encryption, the second field of the message) |
35 | MsgType | Y | Message type (non-encryption, the third field of the message) |
49 | SenderCompID | Y | Code sender (not encrypted, the sender identifier) |
59 | TargetCompID | Y | The code receiver (not encrypted receiver identifier) |
115 | OnBehalfOfCompID | N | Initially sender identifier (may be encrypted), by a third party for transmitting. |
128 | DeliverToCompID | N | The final recipient identifier (may be encrypted), by a third party for transmitting. |
90 | SecureDataLen | N | Ciphertext data length |
91 | SecureData | N | Ciphertext data (ciphertext data length field immediately) |
34 | MsgSeqNum | Y | Message sequence number (may be encrypted), if the parties to the transaction FIX session mechanism is not used, the tag may be set to a fixed value, such as zero. |
50 | SenderSubID | N | Prescription transmission identifier (may be encrypted) |
142 | SenderLocationID | N | Orientation sender identifier (may be encrypted) |
57 | TargetSubID | N | Receiving a recipe identifier (may be encrypted) |
143 | TargetLocationID | N | Orientation recipient identifier (may be encrypted) |
116 | OnBehalfOfSubID | N | Initially transmitted recipe identifier (may be encrypted) |
144 | OnBehalfOfLocationID | N | Initially orientation sender identifier (may be encrypted) |
129 | DeliverToSubID | N | The final prescription received identifier (may be encrypted) |
145 | DeliverToLocationID | N | Orientation ultimate recipient identifier (may be encrypted) |
43 | PossDupFlag | N | Signs may be repeated, repeated sending, for this tag. (Encrypt) |
97 | Yes *** esend | N | May retransmit flag. (Encrypt) |
52 | SendingTime | Y | Transmission time (may be encrypted) |
122 | OrigSendingTime | N | 原始发送时间(可加密) |
347 | MessageEncoding | N | 消息中 Encoded 域的字符编码类型(非 ASCII 码) |
369 | LastMsgSeqNumProcesse d | N | 最后处理消息序号(可加密) |
370 | OnBehalfOfSendingTime | N | 最初发送时间(用 UTC 表示时间) |
消息尾
每一个消息(会话或应用消息)有一个消息尾,并以此终止。消息尾可用于分隔多个消息,包含有 3 位数的校验和值。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
93 | SignatureLength | N | 数字签名长度(不可加密) |
89 | Signature | N | 数字签名(不可加密) |
10 | CheckSum | Y | 校验和,消息的最末域。(不可加密) |
新订单消息(MsgType=D)
对于在消息头中设置了 Po***esend 标志的订单消息,应当使用交易客户方订单编号(ClOrdID)核 实是否已收到该订单,具体实现时还应检查订单参数(买卖方向、证券代码、数量等)进行核实。如果 之前收到该订单,应以执行报告消息回应订单状态。如果之前未收到,则以执行报告消息回应订单确认。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=D | |
11 | ClOrdID | Y | 交易客户方订单编号,在订单有效交易日内必需 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易编码 |
110 | MinQty | N | 最小成交量。 |
55 | Symbol | Y | 期货合约代码 |
167 | SecurityType | N | FUT = 期货 |
200 | MaturityMonthYear | N | 用于指定期货到期的年和月 |
205 | MaturityDay | N | 用于期货的到期日期,并被与到期年月(MaturityMonthYear)联合使用 |
207 | SecurityExchange | Y | 用于指定交易所 |
77 | OpenClose | Y | 指明开仓,平仓 |
8009 | HedgeFlag | Y | 投机套保标志 |
8010 | TouchCondition | N | 触发条件 |
54 | Side | Y | 买卖方向 |
38 | OrderQty | N | 委托手数 |
60 | TransactTime | Y | 订单发起时间 |
40 | OrdType | Y | 订单类型 |
44 | Price | N | 价格(限价订单时有效) |
423 | PriceType | N | 价格类型 |
99 | StopPx | N | 停止价 |
15 | Currency | N | 币种 |
59 | TimeInForce | N | 新订单生效时间,默认为当日有效 |
168 | EffectiveTime | N | 用于指定定单有效的时间 |
432 | ExpireDate | N | 有条件地用于在生效时间(TimeInForce)=在某 日前有效(GTD),而没有指定截止时间 (ExpireTime)的情况之下 |
126 | ExpireTime | N | 有条件地用于生效时间(TimeInForce) = 在某 日前有效(GTD)和到期日没有被指定的情况之 下 |
8096 | MacNetInfo | N | 委托方的机器网络信息 |
标准消息尾 | Y |
执行报告消息(MsgType=8)
-
订单确认
-
订单状态变化确认(如撤单确认)
-
发送订单的成交回报
- 订单拒绝
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=8 | |
37 | OrderID | Y | 期货公司委托号,同个交易日必需保证唯一 |
11 | ClOrdID | N | 交易客户方订单编号。如果是强平回报,则该值 取值为以”NONE”开头的当天交易日唯一的字符 串标识 |
42 | OrigClOrdID | N | 原始交易客户方订单编号,指示被撤消订单的 ClOrdID |
17 | ExecID | Y | 期货公司的执行编号,在订单有效交易日内应保证唯一 |
150 | ExecType | Y | 执行类型 |
39 | OrdStatus | Y | 订单状态 |
103 | OrdRejReason | N | 订单拒绝时需要 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易编码 |
55 | Symbol | Y | 期货合约代码 |
167 | SecurityType | N | FUT=期货 |
200 | MaturityMonthYear | N | 到期年月 |
205 | MaturityDay | N | 到期日期 |
207 | SecurityExchange | Y | 用于指定交易所 |
77 | OpenClose | N | 指明开仓,平仓 |
54 | Side | Y | 买卖方向 |
38 | OrderQty | Y | 委托手数 |
40 | OrdType | N | 订单类型 |
44 | Price | N | 订单价格 |
99 | StopPx | N | 停止价 |
59 | TimeInForce | N | 新订单生效时间,默认为当日有效 |
15 | Currency | N | 币种 |
32 | LastShares | N | 上一成交数(最近一笔成交数量) |
31 | LastPx | N | 上一成交价(最近一笔成交价格) |
30 | LastMkt | N | 上一成交市场 |
151 | LeavesQty | Y | 订单剩余数量 |
14 | CumQty | Y | 成交总数 |
6 | AvgPx | Y | 成交平均价 |
60 | TransactTime | N | 执行报告时间 |
381 | GrossTradeAmt | N | 成交总金额 |
110 | MinQty | N | 最小成交量 |
8500 | OrderEntryTime | N | 订单申报时间 |
8093 | DeclarationID | N | 报单号 |
8094 | TradeID | N | 撮合编号 |
标准消息尾 | Y |
订单状态请求消息(MsgType=H)
订单状态请求用于向交易服务方请求某订单的状态,交易服务方通过执行报告消息返回订单状态。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=H | |
37 | OrderID | Y | 期货公司委托号,同个交易日必需保证唯一 |
11 | ClOrdID | Y | 交易客户方订单编号 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易编码 |
55 | Symbol | Y | 期货合约代码 |
207 | SecurityExchange | Y | 用于指定交易所 |
167 | SecurityType | N | FUT=期货 |
200 | MaturityMonthYear | N | 用于指定期货到期的年和月 |
205 | MaturityDay | N | 用于期货的到期日期,并被与到期年月(MaturityMonthYear)联合使用 |
54 | Side | Y | 买卖方向 |
标准消息尾 | Y |
撤单消息(MsgType=F)
撤单消息用以撤消订单的全部订单剩余数量。
撤单消息也被赋予一个 ClOrdID,可视作另外一个订单。如果被拒绝,撤单拒绝消息的 ClOrdID 放 置撤单消息的 ClOrdID,而原始订单的 ClOrdID 则放入 OrigClOrdID 域。ClOrdID 要保证唯一。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=F | |
41 | OrigClOrdID | Y | 原始交易客户方订单编号,指示被撤消订单的ClOrdID |
37 | OrderID | Y | 期货公司委托号,同个交易日必需保证唯一 |
11 | ClOrdID | Y | 交易客户方订单编号 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易编码 |
55 | Symbol | Y | 期货合约代码 |
167 | SecurityType | N | 证券代码源 |
200 | MaturityMonthYear | N | FUT=期货 |
205 | MaturityDay | N | 期货到期年月 |
207 | SecurityExchange | Y | 期货到期日期 |
54 | Side | Y | 买卖方向 |
60 | TransactTime | Y | 订单发起时间 |
40 | OrdType | Y | 订单类型 |
38 | OrderQty | Y | 委托手数 |
8093 | DeclarationID | N | 报单号 |
58 | Text | N | |
标准消息尾 | Y |
撤单拒绝消息(MsgType=9)
本消息用于撤单消息的拒绝。
交易服务方接收到撤单发现无法执行(已成交订单不可更改等),将发送撤单拒绝。
拒绝撤单时,撤单拒绝消息应用 ClOrdID 指示撤单的 ClOrdID,用 OrigClOrdID 指示之前最后接受的订单(除非拒绝原因是“未知订单”)。
Tag | 域名 | 必需 | 说明 |
---|---|---|---|
标准消息头 | Y | MsgType=9 | |
37 | OrderID | Y | 期货公司委托号,同个交易日必需保证唯一 |
11 | ClOrdID | Y | 交易客户方订单编号 |
41 | OrigClOrdID | Y | 原始交易客户方订单编号,指示被撤消订单的ClOrdID |
39 | OrdStatus | Y | 订单状态 |
109 | ClientID | Y | 客户资金帐号 |
1 | Account | Y | 客户交易编码 |
60 | TransactTime | N | 订单发起时间 |
434 | CxlRejResponseTo | N | 撤单拒绝回应类型 |
102 | CxlRejReason | N | 撤单拒绝原因 |
58 | Text | N | |
标准消息尾 | Y |
四、FIX配置
4.1 会话配置(SESSION)
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
BeginString | 会话使用的FIX版本号(发送和接收消息起始字符串) | FIXT.1.1、FIX.4.4、FIX.4.3、FIX.4.2、FIX.4.1、FIX.4.0 | |
SenderCompID | 会话当中定义本方的ID | 区分大小写的字符串 | |
SenderSubID | 会话相关的本方的子ID号 (可选) | 区分大小写的字符串 | |
SenderLocationID | 会话相关的本方的locationID号 (可选) | 区分大小写的字符串 | |
TargetCompID | 本会话当中的对方ID | 区分大小写的字符串 | |
TargetSubID | 本会话当中的对方SubID (可选) | 区分大小写的字符串 | |
TargetLocationID | 本会话当中的对方locationID (可选) | 区分大小写的字符串 | |
SessionQualifier | 附加的限定词,用于消除歧义,保证会话的唯一性 | 区分大小写的字符串 | |
DefaultApplVerID | 仅FIXT1.1(或以上版本)需要。忽略早期版本的传输。指定会话的默认应用程序的版本ID。ApplVerID的枚举值(请看ApplVerID字段详细介绍),或默认BeginString。 | FIX.5.0SP2、FIX.5.0SP1、FIX.5.0、FIX.4.4、FIX.4.3、FIX.4.2、FIX.4.1、FIX.4.0 | |
ConnectionType | 定义会话当中本方的角色:acceptor或者initiator | initiator、acceptor | |
StartTime | 交易日的会话有效开始时间,这时FIX会话被激活 | UTC时间,格式: HH:MM:SS | |
EndTime | 交易日的会话失效时间,FIX会话将被停止 | UTC时间,格式: HH:MM:SS | |
StartDay | 对于为期一周的会话配置,一周会话开始的第一天。与STARTTIME结合使用。 | 使用一周中某天的英语任何缩写都是有效的(比如,mo, mon, mond, monda,Monday都是有效的) | |
EndDay | 对于为期一周的会话配置,一周会话结束的最后一天。与EndTime结合使用。 | 使用一周中某天的英语任何缩写都是有效的(比如,mo, mon, mond, monda,Monday都是有效的) | |
MillisecondsInTimeStamp | 时间戳是否加入毫秒。FIX.4.2和更高版本可用。 | Y、N | Y |
ResetOnLogon | 接收登录请求时,序列号是否要复位。只用于Acceptor | Y、N | N |
ResetOnLogout | 正常注销登录时,序列号是否要复位 | Y、N | N |
ResetOnDisconnect | 连接异常断开后是否要将序列号重置为1 | Y、N | N |
RefreshOnLogon | 确定是否应当从持久层登录时恢复会话状态。在创建热故障切换会话时有用。 | Y、N | N |
EnableLastMsgSeqNumProcessed | 是否在header中添加最后一条消息的序列号(可选tag369)。 | Y、N | N |
MaxMessagesInResendRequest | 设置一次重发请求的消息的最大消息数。 | 任何大于0的整数。使用0为无穷大(默认)。 | 0 |
SendLogoutBeforeDisconnectFromTimeout | 指定是否因超时断开连接之前发送logout消息 | Y、N | N |
IgnorePossDupResendRequests | 当PossDupFlag(tag 43)设置为true时,是否忽略一次重发请求 | Y、N | N |
4.2 验证配置
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
UseDataDictionary | 告诉会话是否使用数据字典,或不希望使用数据字典。 如果你要使用repeating group,你必须使用DataDictionary。 | Y、N | Y |
DataDictionary | 该配置只用于比FIXT.1.1还老的版本。详细参考FIXT.1.1的TransportDataDictionary和AppDataDictionary的配置。 | FIX44.xml、FIX43.xml、FIX42.xml、FIX41.xml、FIX40.xml | |
TransportDataDictionary | XML定义文件用于验证传入的管理消息。如果没有提供DataDictionary,只会做基本消息的验证。该配置只用于FIXT.1.1(或更高版本)的会话。 | FIXT1.1.xml | |
AppDataDictionary | 用于验证应用层消息的XML定义文件。仅对FIXT.1.1(或更高版本)的会话有效。更多信息请参考(FIX.4.0到 FIX.4.4)的DataDictionary。该配置可以为每个会话指定一个自定义应用的数据字典。该配置仅用于FIXT.1.1或更新的传输协议。使用FIXT传输时,该配置可以作为指定多个应用的数据字典的前缀。例如: DefaultApplVerID=FIX.4.2 # For default application version ID AppDataDictionary=FIX42.xml # For nondefault application version ID # Use BeginString suffix for app version AppDataDictionary.FIX.4.4=FIX44.xml | 有效的XML数据字典文件。QuickFIX/N 配备默认的协议字典数据:FIX50SP2.xml、FIX50SP1.xml、FIX50.xml、FIX44.xml、FIX43.xml、FIX42.xml、FIX41.xml、FIX40.xml | |
ValidateFieldsOutOfOrder | 如果设置为N,字段放置区域错误(例如,body字段在header区域内,或在header字段在body区域内)将不会被拒绝。用于连接字段要求不严格的系统。 | Y、N | Y |
ValidateFieldsHaveValues | 如果设置为N,没有值的字段将不会被拒绝。用于连接到系统不当发送空标签。 | Y、N | Y |
ValidateUserDefinedFields | 如果设置为N,用户自定义的字段将不会被拒绝,即使没有在数据字典中定义,或没出现在消息中。 | Y、N | Y |
4.3 Initiator
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
ReconnectInterval | 尝试重新连接的时间间隔(秒)。仅用于 initiator。 | 正整数 | 30 |
HeartBtInt | 心跳间隔(秒)。仅用于initiator。 | 正整数 | - |
LogonTimeout | 登录超时时间间隔(秒) | 正整数 | 10 |
LogoutTimeout | 注销登录超时时间间隔(秒) | 正整数 | 2 |
SocketConnectPort | Socket服务端口,用于建立会话。仅用于 initiator | 正整数 | - |
SocketConnectHost | 连接主机.仅用于 initiator | x.x.x.x格式IP地址或域名 | - |
SocketConnectPort | 一组备用Socket端口,用于连接会话的故障转移,n是正整数。SocketConnectPort1,SocketConnectPort2 ... 必须是连续的,并有一个与之相匹配的数组SocketConnectHost | 正整数 | - |
SocketConnectHost | 一组备用Socket服务主机,用于连接会话的故障转移,n是正整数。SocketConnectHost1, SocketConnectHost2... 必须是连续的,并有一个与之相匹配的数组SocketConnectPort | x.x.x.x格式IP地址或域名 | - |
SocketNodelay | 连接是否禁用Nagle算法。在[DEFAULT]配置节点定义。 | Y、N | Y |
ReconnectInterval | 尝试重新连接的时间间隔(秒)。仅用于 initiator。 | 正整数 | 30 |
4.4 Acceptor
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
SocketAcceptPort | 监听接入连接Socket端口。仅用于acceptor | 正整数,有效的、开放的套接字端口 | - |
SocketAcceptHost | 监听接入连接的Socket服务的主机。如果不提供,acceptor将监听所有网络端口(0.0.0.0) | 有效的x.x.x.x格式IP地址 | 0.0.0.0 |
SocketNodelay | 连接是否禁用Nagle算法。在[DEFAULT]配置节点定义。 | Y、N | Y |
4.5 Storage
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
PersistMessages | 如果设置为N,被不会保存消息。这样将迫使quickfix总是发送GapFills,而不是重新发送消息。如果你知道你永远不需要重新发送消息,使用此配置。有用的市场数据流。 | Y、N | Y |
4.6 File Storage
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
FileStorePath | 存储序列号和消息的文件目录。 | 有效的文件存储目录,必须有写入权限。 | - |
4.7 Logging
配置 | 描述 | 有效值 | 默认 |
---|---|---|---|
FileLogPath | Directory to store logs. | Effective file storage directory, you must have write permission. | - |
Five, FIX Development
5.1 FIX engine
- Official website: FIX engine ( http://www.quickfixengine.org/ )
github:QFJ GitHub Repository(https://github.com/quickfix-j/quickfixj)
5.2 DEMO
Acceptor profile
# 定义会话的默认配置(default节点)
[DEFAULT]
FileStorePath=store
FileLogPath=log
ConnectionType=acceptor
ReconnectInterval=60
SenderCompID=SERVER
ResetOnDisconnect=Y
ResetOnLogout=Y
ResetOnLogon=Y
[SESSION]
BeginString=FIX.4.2
TargetCompID=CLIENT
StartTime=00:00:00
EndTime=23:59:59
HeartBtInt=30
SocketAcceptHost=127.0.0.1
SocketAcceptPort=6666
DataDictionary=FIX42.xml
Initiator profile
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=60
FileLogPath=log
FileStorePath=store
StartTime=00:00:00
EndTime=23:59:59
HeartBtInt=30
ResetOnDisconnect=Y
ResetOnLogout=Y
ResetOnLogon=Y
[SESSION]
BeginString=FIX.4.2
SenderCompID=CLIENT
TargetCompID=SERVER
SocketConnectPort=6666
SocketConnectHost=127.0.0.1
DataDictionary=FIX42.xml
FixServer
package com.app.fix;
import quickfix.*;
/**
* 服务启动主类(线程)
*/
public class FixServer {
private static ThreadedSocketAcceptor acceptor = null;
/**
* 指定配置文件启动
*
* @param propFile
* @throws ConfigError
* @throws FieldConvertError
*/
public FixServer(String propFile) throws ConfigError, FieldConvertError {
// 设置配置文件
SessionSettings settings = new SessionSettings(propFile);
// 设置一个APPlication
Application application = new FixServerApplication();
/**
*
* quickfix.MessageStore 有2种实现。 quickfix.JdbcStore,quickfix.FileStore .
* JdbcStoreFactory 负责创建JdbcStore , FileStoreFactory 负责创建FileStorequickfix
* 默认用文件存储,因为文件存储效率高。
*/
MessageStoreFactory storeFactory = new FileStoreFactory(settings);
LogFactory logFactory = new FileLogFactory(settings);
MessageFactory messageFactory = new DefaultMessageFactory();
acceptor = new ThreadedSocketAcceptor(application, storeFactory, settings, logFactory, messageFactory);
}
private void startServer() throws RuntimeError, ConfigError {
acceptor.start();
}
/**
* 测试本地使用的main方法
*
* @param args
* @throws FieldConvertError
* @throws ConfigError
*/
public static void main(String[] args) throws ConfigError, FieldConvertError {
FixServer fixServer = new FixServer("res/acceptor.config");
fixServer.startServer();
}
}
FixServerApplication
package com.app.fix;
import quickfix.Application;
import quickfix.DoNotSend;
import quickfix.FieldNotFound;
import quickfix.IncorrectDataFormat;
import quickfix.IncorrectTagValue;
import quickfix.Message;
import quickfix.MessageCracker;
import quickfix.RejectLogon;
import quickfix.Session;
import quickfix.SessionID;
import quickfix.UnsupportedMessageType;
import quickfix.field.MsgType;
/**
*
*/
public class FixServerApplication extends MessageCracker implements Application {
@Override
protected void onMessage(Message message, SessionID sessionID) {
try {
String msgType = message.getHeader().getString(35);
Session session = Session.lookupSession(sessionID);
switch (msgType) {
case MsgType.LOGON: // 登陆
session.logon();
session.sentLogon();
break;
case MsgType.HEARTBEAT: // 心跳
session.generateHeartbeat();
break;
}
} catch (FieldNotFound e) {
e.printStackTrace();
}
}
@Override
public void onCreate(SessionID sessionId) {
System.out.println(" 服务器启动时候调用此方法创建");
}
@Override
public void onLogon(SessionID sessionId) {
System.out.println("客户端登陆成功时候调用此方法");
}
@Override
public void onLogout(SessionID sessionId) {
System.out.println("客户端断开连接时候调用此方法");
}
@Override
public void toAdmin(Message message, SessionID sessionId) {
System.out.println("发送会话消息时候调用此方法");
}
@Override
public void toApp(Message message, SessionID sessionId) throws DoNotSend {
System.out.println("发送业务消息时候调用此方法");
}
@Override
public void fromAdmin(Message message, SessionID sessionId)
throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
System.out.println("接收会话类型消息时调用此方法");
try {
crack(message, sessionId);
} catch (UnsupportedMessageType | FieldNotFound | IncorrectTagValue e) {
e.printStackTrace();
}
}
@Override
public void fromApp(Message message, SessionID sessionId)
throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
System.out.println("接收业务消息时调用此方法");
crack(message, sessionId);
}
}
FixClient
package com.app.fix;
import quickfix.*;
import quickfix.field.*;
import quickfix.fix42.NewOrderSingle;
import java.io.FileNotFoundException;
import java.util.Date;
public class FixClient implements Application {
private static volatile SessionID sessionID;
@Override
public void onCreate(SessionID sessionID) {
System.out.println("OnCreate");
}
@Override
public void onLogon(SessionID sessionID) {
System.out.println("OnLogon");
FixClient.sessionID = sessionID;
}
@Override
public void onLogout(SessionID sessionID) {
System.out.println("OnLogout");
FixClient.sessionID = null;
}
@Override
public void toAdmin(Message message, SessionID sessionID) {
System.out.println("ToAdmin");
}
@Override
public void fromAdmin(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
System.out.println("FromAdmin");
}
@Override
public void toApp(Message message, SessionID sessionID) throws DoNotSend {
System.out.println("ToApp: " + message);
}
@Override
public void fromApp(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
System.out.println("FromApp");
}
public static void main(String[] args) throws ConfigError, FileNotFoundException, InterruptedException, SessionNotFound {
SessionSettings settings = new SessionSettings("res/initiator.config");
Application application = new FixClient();
MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
LogFactory logFactory = new ScreenLogFactory(true, true, true);
MessageFactory messageFactory = new DefaultMessageFactory();
Initiator initiator = new SocketInitiator(application, messageStoreFactory, settings, logFactory, messageFactory);
initiator.start();
while (sessionID == null) {
Thread.sleep(1000);
}
final String orderId = "342";
NewOrderSingle newOrder = new NewOrderSingle(new ClOrdID(orderId), new HandlInst('1'), new Symbol("YRD"),
new Side(Side.BUY), new TransactTime(new Date()), new OrdType(OrdType.MARKET));
Session.sendToTarget(newOrder, sessionID);
Thread.sleep(5000);
}
}
Author: JIANG Yong Nian
Source: CreditEase Institute of Technology