溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何理解FIX協(xié)議的原理、消息格式及配置開(kāi)發(fā)

發(fā)布時(shí)間:2021-11-23 17:58:26 來(lái)源:億速云 閱讀:231 作者:柒染 欄目:軟件技術(shù)

本篇文章給大家分享的是有關(guān)如何理解FIX協(xié)議的原理、消息格式及配置開(kāi)發(fā),小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著小編一起來(lái)看看吧。

一、定義

FIX協(xié)議是由國(guó)際FIX協(xié)會(huì)組織提供的一個(gè)開(kāi)放式協(xié)議,目的是推動(dòng)國(guó)際貿(mào)易電子化的進(jìn)程,在各類(lèi)參與者之間,包括投資經(jīng)理、經(jīng)紀(jì)人,買(mǎi)方、賣(mài)方建立起實(shí)時(shí)的電子化通訊協(xié)議。FIX協(xié)議的目標(biāo)是把各類(lèi)證券金融業(yè)務(wù)需求流程格式化,使之成為一個(gè)個(gè)可用計(jì)算機(jī)語(yǔ)言描述的功能流程,并在每個(gè)業(yè)務(wù)功能接口上統(tǒng)一交換格式,方便各個(gè)功能模塊的連接。

二、協(xié)議工作原理

2.1 通信模型及基本概念

通信模型

  • Initiator :發(fā)起者,建立通信連路,通過(guò)發(fā)送初始Logon消息發(fā)起會(huì)話(huà)的參與方。

  • Acceptor :接收方 FIX會(huì)話(huà)的接收方。負(fù)責(zé)執(zhí)行第一層次的認(rèn)證和通過(guò)傳輸Logon消息的確認(rèn)正式聲明連接請(qǐng)求被接受。

  • 原則:先發(fā)起者為Initiator ,接受者為Acceptor 。

  • 標(biāo)準(zhǔn)模式以網(wǎng)關(guān)為Acceptor,客戶(hù)端為Initiator做為常用模式。

Fix connection

FIX連接 由3部分組成:logon登錄,message exchange消息傳輸,logout注銷(xiāo)。

  • logon登錄 

如何理解FIX協(xié)議的原理、消息格式及配置開(kāi)發(fā)

  • logout注銷(xiāo) 

如何理解FIX協(xié)議的原理、消息格式及配置開(kāi)發(fā)

Fix session

FIX會(huì)話(huà)由一個(gè)或多個(gè)FIX Connection FIX連接組成。一個(gè)FIX會(huì)話(huà)可以有多次登錄。

序列號(hào)

  • 所有的FIX消息都由一個(gè)唯一的序列號(hào)進(jìn)行標(biāo)示。序列號(hào)在每一個(gè)FIX會(huì)話(huà)開(kāi)始時(shí)被初始化為1,并在整個(gè)會(huì)話(huà)期間遞增。監(jiān)控序列號(hào)可以使會(huì)話(huà)參與者識(shí)別和處理丟失的消息,當(dāng)在一個(gè)FIX會(huì)話(huà)中重新連接時(shí)能夠快速進(jìn)行應(yīng)用程序同步。

  • 每個(gè)會(huì)話(huà)將建立一組互不依賴(lài)的接受和發(fā)送序列。會(huì)話(huà)參與者將維護(hù)一個(gè)賦予發(fā)送消息的序列和一個(gè)監(jiān)控接受消息的消息塊間隙序列號(hào)。

心跳

  • 在消息交互期間,F(xiàn)IX應(yīng)用程序?qū)⒅芷谛援a(chǎn)生Heartbeat心跳消息。該心跳消息可以監(jiān)控通信鏈路狀態(tài)及識(shí)別接收序列號(hào)間隙。發(fā)送Heartbeat的周期間隔由會(huì)話(huà)發(fā)起者使用在Logon消息中HeartBtInt域進(jìn)行定義。

  • Heartbeat心跳消息的時(shí)間間隔應(yīng)當(dāng)在每一個(gè)消息發(fā)送后復(fù)位,即發(fā)送一個(gè)消息后,在間隔給定的時(shí)間內(nèi)無(wú)其它消息發(fā)送則發(fā)送一個(gè)Heartbeat心跳消息。HeartBtInt的值應(yīng)當(dāng)被會(huì)話(huà)雙方認(rèn)同,由會(huì)話(huà)發(fā)起方定義并由會(huì)話(huà)接收者通過(guò)Logon消息進(jìn)行確認(rèn)。同一個(gè)HeartBtInt被會(huì)話(huà)雙方——登錄的發(fā)起者和登錄的接受者共同使用。

數(shù)據(jù)完整校驗(yàn)

  • 消息數(shù)據(jù)內(nèi)容的完整性可以參用兩種方式來(lái)驗(yàn)證:消息長(zhǎng)度和效驗(yàn)碼檢查。

  • 程序通過(guò)計(jì)算BodyLength域到CheckSum標(biāo)記(“10=”)分界符的字符數(shù),域BodyLength標(biāo)示的消息長(zhǎng)度進(jìn)行比較來(lái)完成完整性效驗(yàn)。

  • ChekSum完整性檢查,通過(guò)計(jì)算從域“8=” 中“8”開(kāi)始,包括緊跟在CheckSum標(biāo)記域的分界符每個(gè)字符的2進(jìn)制和同CheckSum進(jìn)行比較得到。

  • 一個(gè)FIX消息校驗(yàn)和通過(guò)計(jì)算到ChechSum域(但不包括)的消息的每個(gè)字節(jié)和得到。然后,校驗(yàn)和被轉(zhuǎn)換為模256的數(shù)字用于傳送和比較。校驗(yàn)和在所有加密操作之后被計(jì)算。

校驗(yàn)代碼:

樣例:8=FIX.4.29=7335=A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y10=208
1、消息長(zhǎng)度:9=73
35=A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y(這段長(zhǎng)度)
2、效驗(yàn)碼檢查
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 );
}

消息確認(rèn)

  • FIX協(xié)議不支持單個(gè)消息的確認(rèn)。采用的是監(jiān)控消息時(shí)隙的方法來(lái)進(jìn)行消息恢復(fù)和驗(yàn)證。

  • 普通的數(shù)據(jù)傳送(無(wú)單個(gè)消息確認(rèn))通過(guò)消息序列間隙進(jìn)行錯(cuò)誤識(shí)別。每個(gè)消息由一個(gè)唯一的序列號(hào)進(jìn)行標(biāo)示。接收端應(yīng)用程序負(fù)責(zé)監(jiān)控接收消息序列號(hào)以識(shí)別消息間隙并產(chǎn)生重傳請(qǐng)求。

  • 每個(gè)FIX參與方必須為FIX會(huì)話(huà)維護(hù)兩個(gè)序列號(hào),一個(gè)是接收序列號(hào),一個(gè)是發(fā)送序列號(hào),兩者都在建立FIX會(huì)話(huà)開(kāi)始時(shí)初始化為1。每個(gè)消息被賦予一個(gè)唯一的序列號(hào)值,并在消息發(fā)送后遞增。此外,每個(gè)收到的消息都有一個(gè)唯一的序列號(hào),接收序列號(hào)計(jì)數(shù)器在收到每個(gè)消息后將會(huì)被遞增。

  • 當(dāng)接收序列號(hào)與所希望得到的的正確序列號(hào)不必配時(shí),必須采取糾錯(cuò)處理。

加密

  • 加密算法由連接雙方共同協(xié)商。

  • 一個(gè)消息的任何一個(gè)域可以被加密并放在SecureData域中。然而,一些顯示的標(biāo)志域必須采用明文進(jìn)行傳輸。為確保完整性,明文域可以在SecureData域中重復(fù)。

  • 當(dāng)使用加密時(shí),建議但不是必須,所有的消息體都進(jìn)行加密。如果一個(gè)消息中的重復(fù)組數(shù)據(jù)中的部分?jǐn)?shù)據(jù)要加密,這個(gè)重復(fù)組必須全部進(jìn)行加密。

  • 預(yù)先協(xié)商好的加密算法在Logon消息中進(jìn)行聲明。

自定義域

  • FIX為給用戶(hù)提供最大的靈活性,F(xiàn)IX協(xié)議允許用戶(hù)自定義域。這些域在認(rèn)同的參與者之間實(shí)現(xiàn)、應(yīng)用,并且應(yīng)注意避免沖突。

  • Tag數(shù)在5000 到9999保留用于用戶(hù)自定義域。這些tag值用于企業(yè)聯(lián)盟的信息交換??梢酝ㄟ^(guò)FIX網(wǎng)站進(jìn)行注冊(cè)。

  • 10000以上保留用于單一企業(yè)內(nèi)部使用。不用注冊(cè)。

三、消息格式

3.1 數(shù)據(jù)類(lèi)型

整數(shù)int,浮點(diǎn)數(shù)float,單個(gè)字符char,布爾Boolean,字符串String,數(shù)據(jù)data 

3.2 域

常見(jiàn)域

Tag(標(biāo)記)FieldName(域名)備注
8BeginString起始串,F(xiàn)IX協(xié)議版本
9BodyLength消息長(zhǎng)度
35MsgType消息類(lèi)型:例如F=Order Cancel Request,取消訂單
11ClOrdID客戶(hù)端訂單ID
37OrderID服務(wù)端訂單ID
41OrigClOrdID原始客戶(hù)端訂單ID
54Side買(mǎi)賣(mài)類(lèi)型。例如:1 = Buy,2 = Sell
55Symbol股票代碼。例如:YRD
10CheckSum校驗(yàn)碼

域語(yǔ)法

  • 開(kāi)始部分應(yīng)是消息頭,隨后是正文,最后是消息尾;

  • 消息頭的前 3 個(gè)域的次序不能改變:起始串(Tag =8)、消息體長(zhǎng)度(Tag =9)、消息類(lèi)型(Tag =35);

  • 消息尾的最后一個(gè)域應(yīng)是校驗(yàn)和域(Tag=10);

  • 重復(fù)組中,域出現(xiàn)的順序應(yīng)遵循該重復(fù)組在消息或組件中定義時(shí)的次序;

  • 在一條消息中,除重復(fù)組域外任何其他域不能重復(fù)出現(xiàn)。

安全與加密

  • 由于消息有可能在公網(wǎng)或不安全的網(wǎng)絡(luò)上傳輸交換,因此需要對(duì)相關(guān)的敏感數(shù)據(jù)加密處理。

  • 具體加密的方法由連接雙方達(dá)成的協(xié)議而定。

  • 消息內(nèi)除某些需要公開(kāi)識(shí)別的域以明文傳輸外其他任何域都可以加密放置密文數(shù)據(jù)域 (SecureData)內(nèi)。當(dāng)然,這些被加密的域也可以同時(shí)保留明文的表示方式。

  • 當(dāng)決定使用加密方案時(shí),可以對(duì)消息正文內(nèi)所有的域加密。如果消息的重復(fù)組內(nèi)有部分需要加密的,那么要求對(duì)整個(gè)重復(fù)組加密。

  • 本協(xié)議還提供的一些域用以支持?jǐn)?shù)字簽名、密鑰交換和正文加密等安全技術(shù)。

3.3 消息

消息頭

每一個(gè)會(huì)話(huà)或應(yīng)用消息有一個(gè)消息頭,該消息頭指明消息類(lèi)型、消息體長(zhǎng)度、發(fā)送目的地、消息序號(hào)、發(fā)送起始點(diǎn)和發(fā)送時(shí)間。

Tag域名必需說(shuō)明
8BeginStringY起始串,取值:FIX.4.2(不可加密,消息的第一個(gè)域)
9BodyLengthY消息體長(zhǎng)度(不可加密,消息的第二個(gè)域)
35MsgTypeY消息類(lèi)型(不可加密,消息的第三個(gè)域)
49SenderCompIDY發(fā)送方代碼(不可加密,發(fā)送方標(biāo)識(shí)符)
59TargetCompIDY接收方代碼(不可加密,接收方標(biāo)識(shí)符)
115OnBehalfOfCompIDN最初發(fā)送方標(biāo)識(shí)符(可加密),用于經(jīng)第三方發(fā)送。
128DeliverToCompIDN最終接收方標(biāo)識(shí)符(可加密),用于經(jīng)第三方發(fā)送。
90SecureDataLenN密文數(shù)據(jù)長(zhǎng)度
91SecureDataN密文數(shù)據(jù)(緊跟密文數(shù)據(jù)長(zhǎng)度域)
34MsgSeqNumY消息序號(hào)(可加密),如果交易雙方不采用 FIX 會(huì)話(huà) 機(jī)制,可將該 tag 置為一個(gè)固定的值,例如 0。
50SenderSubIDN發(fā)送方子標(biāo)識(shí)符(可加密)
142SenderLocationIDN發(fā)送方方位標(biāo)識(shí)符(可加密)
57TargetSubIDN接收方子標(biāo)識(shí)符(可加密)
143TargetLocationIDN接收方方位標(biāo)識(shí)符(可加密)
116OnBehalfOfSubIDN最初發(fā)送方子標(biāo)識(shí)符(可加密)
144OnBehalfOfLocationIDN最初發(fā)送方方位標(biāo)識(shí)符(可加密)
129DeliverToSubIDN最終接收方子標(biāo)識(shí)符(可加密)
145DeliverToLocationIDN最終接收方方位標(biāo)識(shí)符(可加密)
43PossDupFlagN可能重復(fù)標(biāo)志,重復(fù)發(fā)送時(shí),作此標(biāo)記。(可加密)
97PossResendN可能重發(fā)標(biāo)志。(可加密)
52SendingTimeY發(fā)送時(shí)間(可加密)
122OrigSendingTimeN原始發(fā)送時(shí)間(可加密)
347MessageEncodingN消息中 Encoded 域的字符編碼類(lèi)型(非 ASCII 碼)
369LastMsgSeqNumProcesse dN最后處理消息序號(hào)(可加密)
370OnBehalfOfSendingTimeN最初發(fā)送時(shí)間(用 UTC 表示時(shí)間)

消息尾

每一個(gè)消息(會(huì)話(huà)或應(yīng)用消息)有一個(gè)消息尾,并以此終止。消息尾可用于分隔多個(gè)消息,包含有 3 位數(shù)的校驗(yàn)和值。

Tag域名必需說(shuō)明
93SignatureLengthN數(shù)字簽名長(zhǎng)度(不可加密)
89SignatureN數(shù)字簽名(不可加密)
10CheckSumY校驗(yàn)和,消息的最末域。(不可加密)

新訂單消息(MsgType=D)

對(duì)于在消息頭中設(shè)置了 PossResend 標(biāo)志的訂單消息,應(yīng)當(dāng)使用交易客戶(hù)方訂單編號(hào)(ClOrdID)核 實(shí)是否已收到該訂單,具體實(shí)現(xiàn)時(shí)還應(yīng)檢查訂單參數(shù)(買(mǎi)賣(mài)方向、證券代碼、數(shù)量等)進(jìn)行核實(shí)。如果 之前收到該訂單,應(yīng)以執(zhí)行報(bào)告消息回應(yīng)訂單狀態(tài)。如果之前未收到,則以執(zhí)行報(bào)告消息回應(yīng)訂單確認(rèn)。

如何理解FIX協(xié)議的原理、消息格式及配置開(kāi)發(fā)

Tag域名必需說(shuō)明

標(biāo)準(zhǔn)消息頭YMsgType=D
11ClOrdIDY交易客戶(hù)方訂單編號(hào),在訂單有效交易日內(nèi)必需
109ClientIDY客戶(hù)資金帳號(hào)
1AccountY客戶(hù)交易編碼
110MinQtyN最小成交量。
55SymbolY期貨合約代碼
167SecurityTypeNFUT = 期貨
200MaturityMonthYearN用于指定期貨到期的年和月
205MaturityDayN用于期貨的到期日期,并被與到期年月(MaturityMonthYear)聯(lián)合使用
207SecurityExchangeY用于指定交易所
77OpenCloseY指明開(kāi)倉(cāng),平倉(cāng)
8009HedgeFlagY投機(jī)套保標(biāo)志
8010TouchConditionN觸發(fā)條件
54SideY買(mǎi)賣(mài)方向
38OrderQtyN委托手?jǐn)?shù)
60TransactTimeY訂單發(fā)起時(shí)間
40OrdTypeY訂單類(lèi)型
44PriceN價(jià)格(限價(jià)訂單時(shí)有效)
423PriceTypeN價(jià)格類(lèi)型
99StopPxN停止價(jià)
15CurrencyN幣種
59TimeInForceN新訂單生效時(shí)間,默認(rèn)為當(dāng)日有效
168EffectiveTimeN用于指定定單有效的時(shí)間
432ExpireDateN有條件地用于在生效時(shí)間(TimeInForce)=在某 日前有效(GTD),而沒(méi)有指定截止時(shí)間 (ExpireTime)的情況之下
126ExpireTimeN有條件地用于生效時(shí)間(TimeInForce) = 在某 日前有效(GTD)和到期日沒(méi)有被指定的情況之 下
8096MacNetInfoN委托方的機(jī)器網(wǎng)絡(luò)信息

標(biāo)準(zhǔn)消息尾Y

執(zhí)行報(bào)告消息(MsgType=8)

  • 訂單確認(rèn)

  • 訂單狀態(tài)變化確認(rèn)(如撤單確認(rèn))

  • 發(fā)送訂單的成交回報(bào)

  • 訂單拒絕

Tag域名必需說(shuō)明

標(biāo)準(zhǔn)消息頭YMsgType=8
37OrderIDY期貨公司委托號(hào),同個(gè)交易日必需保證唯一
11ClOrdIDN交易客戶(hù)方訂單編號(hào)。如果是強(qiáng)平回報(bào),則該值 取值為以”NONE”開(kāi)頭的當(dāng)天交易日唯一的字符 串標(biāo)識(shí)
42OrigClOrdIDN原始交易客戶(hù)方訂單編號(hào),指示被撤消訂單的 ClOrdID
17ExecIDY期貨公司的執(zhí)行編號(hào),在訂單有效交易日內(nèi)應(yīng)保證唯一
150ExecTypeY執(zhí)行類(lèi)型
39OrdStatusY訂單狀態(tài)
103OrdRejReasonN訂單拒絕時(shí)需要
109ClientIDY客戶(hù)資金帳號(hào)
1AccountY客戶(hù)交易編碼
55SymbolY期貨合約代碼
167SecurityTypeNFUT=期貨
200MaturityMonthYearN到期年月
205MaturityDayN到期日期
207SecurityExchangeY用于指定交易所
77OpenCloseN指明開(kāi)倉(cāng),平倉(cāng)
54SideY買(mǎi)賣(mài)方向
38OrderQtyY委托手?jǐn)?shù)
40OrdTypeN訂單類(lèi)型
44PriceN訂單價(jià)格
99StopPxN停止價(jià)
59TimeInForceN新訂單生效時(shí)間,默認(rèn)為當(dāng)日有效
15CurrencyN幣種
32LastSharesN上一成交數(shù)(最近一筆成交數(shù)量)
31LastPxN上一成交價(jià)(最近一筆成交價(jià)格)
30LastMktN上一成交市場(chǎng)
151LeavesQtyY訂單剩余數(shù)量
14CumQtyY成交總數(shù)
6AvgPxY成交平均價(jià)
60TransactTimeN執(zhí)行報(bào)告時(shí)間
381GrossTradeAmtN成交總金額
110MinQtyN最小成交量
8500OrderEntryTimeN訂單申報(bào)時(shí)間
8093DeclarationIDN報(bào)單號(hào)
8094TradeIDN撮合編號(hào)

標(biāo)準(zhǔn)消息尾Y

訂單狀態(tài)請(qǐng)求消息(MsgType=H)

訂單狀態(tài)請(qǐng)求用于向交易服務(wù)方請(qǐng)求某訂單的狀態(tài),交易服務(wù)方通過(guò)執(zhí)行報(bào)告消息返回訂單狀態(tài)。

Tag域名必需說(shuō)明

標(biāo)準(zhǔn)消息頭YMsgType=H
37OrderIDY期貨公司委托號(hào),同個(gè)交易日必需保證唯一
11ClOrdIDY交易客戶(hù)方訂單編號(hào)
109ClientIDY客戶(hù)資金帳號(hào)
1AccountY客戶(hù)交易編碼
55SymbolY期貨合約代碼
207SecurityExchangeY用于指定交易所
167SecurityTypeNFUT=期貨
200MaturityMonthYearN用于指定期貨到期的年和月
205MaturityDayN用于期貨的到期日期,并被與到期年月(MaturityMonthYear)聯(lián)合使用
54SideY買(mǎi)賣(mài)方向

標(biāo)準(zhǔn)消息尾Y

撤單消息(MsgType=F)

撤單消息用以撤消訂單的全部訂單剩余數(shù)量。

撤單消息也被賦予一個(gè) ClOrdID,可視作另外一個(gè)訂單。如果被拒絕,撤單拒絕消息的 ClOrdID 放 置撤單消息的 ClOrdID,而原始訂單的 ClOrdID 則放入 OrigClOrdID 域。ClOrdID 要保證唯一。

Tag域名必需說(shuō)明

標(biāo)準(zhǔn)消息頭YMsgType=F
41OrigClOrdIDY原始交易客戶(hù)方訂單編號(hào),指示被撤消訂單的ClOrdID
37OrderIDY期貨公司委托號(hào),同個(gè)交易日必需保證唯一
11ClOrdIDY交易客戶(hù)方訂單編號(hào)
109ClientIDY客戶(hù)資金帳號(hào)
1AccountY客戶(hù)交易編碼
55SymbolY期貨合約代碼
167SecurityTypeN證券代碼源
200MaturityMonthYearNFUT=期貨
205MaturityDayN期貨到期年月
207SecurityExchangeY期貨到期日期
54SideY買(mǎi)賣(mài)方向
60TransactTimeY訂單發(fā)起時(shí)間
40OrdTypeY訂單類(lèi)型
38OrderQtyY委托手?jǐn)?shù)
8093DeclarationIDN報(bào)單號(hào)
58TextN

標(biāo)準(zhǔn)消息尾Y

撤單拒絕消息(MsgType=9)

本消息用于撤單消息的拒絕。

交易服務(wù)方接收到撤單發(fā)現(xiàn)無(wú)法執(zhí)行(已成交訂單不可更改等),將發(fā)送撤單拒絕。

拒絕撤單時(shí),撤單拒絕消息應(yīng)用 ClOrdID 指示撤單的 ClOrdID,用 OrigClOrdID 指示之前最后接受的訂單(除非拒絕原因是“未知訂單”)。

Tag域名必需說(shuō)明

標(biāo)準(zhǔn)消息頭YMsgType=9
37OrderIDY期貨公司委托號(hào),同個(gè)交易日必需保證唯一
11ClOrdIDY交易客戶(hù)方訂單編號(hào)
41OrigClOrdIDY原始交易客戶(hù)方訂單編號(hào),指示被撤消訂單的ClOrdID
39OrdStatusY訂單狀態(tài)
109ClientIDY客戶(hù)資金帳號(hào)
1AccountY客戶(hù)交易編碼
60TransactTimeN訂單發(fā)起時(shí)間
434CxlRejResponseToN撤單拒絕回應(yīng)類(lèi)型
102CxlRejReasonN撤單拒絕原因
58TextN

標(biāo)準(zhǔn)消息尾Y

四、FIX配置

4.1 會(huì)話(huà)配置(SESSION)

配置描述有效值默認(rèn)
BeginString會(huì)話(huà)使用的FIX版本號(hào)(發(fā)送和接收消息起始字符串)FIXT.1.1、FIX.4.4、FIX.4.3、FIX.4.2、FIX.4.1、FIX.4.0
SenderCompID會(huì)話(huà)當(dāng)中定義本方的ID區(qū)分大小寫(xiě)的字符串
SenderSubID會(huì)話(huà)相關(guān)的本方的子ID號(hào) (可選)區(qū)分大小寫(xiě)的字符串
SenderLocationID會(huì)話(huà)相關(guān)的本方的locationID號(hào) (可選)區(qū)分大小寫(xiě)的字符串
TargetCompID本會(huì)話(huà)當(dāng)中的對(duì)方ID區(qū)分大小寫(xiě)的字符串
TargetSubID本會(huì)話(huà)當(dāng)中的對(duì)方SubID (可選)區(qū)分大小寫(xiě)的字符串
TargetLocationID本會(huì)話(huà)當(dāng)中的對(duì)方locationID (可選)區(qū)分大小寫(xiě)的字符串
SessionQualifier附加的限定詞,用于消除歧義,保證會(huì)話(huà)的唯一性區(qū)分大小寫(xiě)的字符串
DefaultApplVerID僅FIXT1.1(或以上版本)需要。忽略早期版本的傳輸。指定會(huì)話(huà)的默認(rèn)應(yīng)用程序的版本ID。ApplVerID的枚舉值(請(qǐng)看ApplVerID字段詳細(xì)介紹),或默認(rèn)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定義會(huì)話(huà)當(dāng)中本方的角色:acceptor或者initiatorinitiator、acceptor
StartTime交易日的會(huì)話(huà)有效開(kāi)始時(shí)間,這時(shí)FIX會(huì)話(huà)被激活UTC時(shí)間,格式: HH:MM:SS
EndTime交易日的會(huì)話(huà)失效時(shí)間,F(xiàn)IX會(huì)話(huà)將被停止UTC時(shí)間,格式: HH:MM:SS
StartDay對(duì)于為期一周的會(huì)話(huà)配置,一周會(huì)話(huà)開(kāi)始的第一天。與STARTTIME結(jié)合使用。使用一周中某天的英語(yǔ)任何縮寫(xiě)都是有效的(比如,mo, mon, mond, monda,Monday都是有效的)
EndDay對(duì)于為期一周的會(huì)話(huà)配置,一周會(huì)話(huà)結(jié)束的最后一天。與EndTime結(jié)合使用。使用一周中某天的英語(yǔ)任何縮寫(xiě)都是有效的(比如,mo, mon, mond, monda,Monday都是有效的)
MillisecondsInTimeStamp時(shí)間戳是否加入毫秒。FIX.4.2和更高版本可用。Y、NY
ResetOnLogon接收登錄請(qǐng)求時(shí),序列號(hào)是否要復(fù)位。只用于AcceptorY、NN
ResetOnLogout正常注銷(xiāo)登錄時(shí),序列號(hào)是否要復(fù)位Y、NN
ResetOnDisconnect連接異常斷開(kāi)后是否要將序列號(hào)重置為1Y、NN
RefreshOnLogon確定是否應(yīng)當(dāng)從持久層登錄時(shí)恢復(fù)會(huì)話(huà)狀態(tài)。在創(chuàng)建熱故障切換會(huì)話(huà)時(shí)有用。Y、NN
EnableLastMsgSeqNumProcessed是否在header中添加最后一條消息的序列號(hào)(可選tag369)。Y、NN
MaxMessagesInResendRequest設(shè)置一次重發(fā)請(qǐng)求的消息的最大消息數(shù)。任何大于0的整數(shù)。使用0為無(wú)窮大(默認(rèn))。
SendLogoutBeforeDisconnectFromTimeout指定是否因超時(shí)斷開(kāi)連接之前發(fā)送logout消息Y、NN
IgnorePossDupResendRequests當(dāng)PossDupFlag(tag 43)設(shè)置為true時(shí),是否忽略一次重發(fā)請(qǐng)求Y、NN

4.2 驗(yàn)證配置

配置描述有效值默認(rèn)
UseDataDictionary告訴會(huì)話(huà)是否使用數(shù)據(jù)字典,或不希望使用數(shù)據(jù)字典。 如果你要使用repeating group,你必須使用DataDictionary。Y、NY
DataDictionary該配置只用于比FIXT.1.1還老的版本。詳細(xì)參考FIXT.1.1的TransportDataDictionary和AppDataDictionary的配置。FIX44.xml、FIX43.xml、FIX42.xml、FIX41.xml、FIX40.xml
TransportDataDictionaryXML定義文件用于驗(yàn)證傳入的管理消息。如果沒(méi)有提供DataDictionary,只會(huì)做基本消息的驗(yàn)證。該配置只用于FIXT.1.1(或更高版本)的會(huì)話(huà)。FIXT1.1.xml
AppDataDictionary用于驗(yàn)證應(yīng)用層消息的XML定義文件。僅對(duì)FIXT.1.1(或更高版本)的會(huì)話(huà)有效。更多信息請(qǐng)參考(FIX.4.0到 FIX.4.4)的DataDictionary。該配置可以為每個(gè)會(huì)話(huà)指定一個(gè)自定義應(yīng)用的數(shù)據(jù)字典。該配置僅用于FIXT.1.1或更新的傳輸協(xié)議。使用FIXT傳輸時(shí),該配置可以作為指定多個(gè)應(yīng)用的數(shù)據(jù)字典的前綴。例如: 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數(shù)據(jù)字典文件。QuickFIX/N 配備默認(rèn)的協(xié)議字典數(shù)據(jù):FIX50SP2.xml、FIX50SP1.xml、FIX50.xml、FIX44.xml、FIX43.xml、FIX42.xml、FIX41.xml、FIX40.xml
ValidateFieldsOutOfOrder如果設(shè)置為N,字段放置區(qū)域錯(cuò)誤(例如,body字段在header區(qū)域內(nèi),或在header字段在body區(qū)域內(nèi))將不會(huì)被拒絕。用于連接字段要求不嚴(yán)格的系統(tǒng)。Y、NY
ValidateFieldsHaveValues如果設(shè)置為N,沒(méi)有值的字段將不會(huì)被拒絕。用于連接到系統(tǒng)不當(dāng)發(fā)送空標(biāo)簽。Y、NY
ValidateUserDefinedFields如果設(shè)置為N,用戶(hù)自定義的字段將不會(huì)被拒絕,即使沒(méi)有在數(shù)據(jù)字典中定義,或沒(méi)出現(xiàn)在消息中。Y、NY

4.3 Initiator

配置描述有效值默認(rèn)
ReconnectInterval嘗試重新連接的時(shí)間間隔(秒)。僅用于 initiator。正整數(shù)30
HeartBtInt心跳間隔(秒)。僅用于initiator。正整數(shù)-
LogonTimeout登錄超時(shí)時(shí)間間隔(秒)正整數(shù)10
LogoutTimeout注銷(xiāo)登錄超時(shí)時(shí)間間隔(秒)正整數(shù)2
SocketConnectPortSocket服務(wù)端口,用于建立會(huì)話(huà)。僅用于 initiator正整數(shù)-
SocketConnectHost連接主機(jī).僅用于 initiatorx.x.x.x格式IP地址或域名-
SocketConnectPort一組備用Socket端口,用于連接會(huì)話(huà)的故障轉(zhuǎn)移,n是正整數(shù)。SocketConnectPort1,SocketConnectPort2 ... 必須是連續(xù)的,并有一個(gè)與之相匹配的數(shù)組SocketConnectHost正整數(shù)-
SocketConnectHost一組備用Socket服務(wù)主機(jī),用于連接會(huì)話(huà)的故障轉(zhuǎn)移,n是正整數(shù)。SocketConnectHost1, SocketConnectHost2... 必須是連續(xù)的,并有一個(gè)與之相匹配的數(shù)組SocketConnectPortx.x.x.x格式IP地址或域名-
SocketNodelay連接是否禁用Nagle算法。在[DEFAULT]配置節(jié)點(diǎn)定義。Y、NY
ReconnectInterval嘗試重新連接的時(shí)間間隔(秒)。僅用于 initiator。正整數(shù)30

4.4 Acceptor

配置描述有效值默認(rèn)
SocketAcceptPort監(jiān)聽(tīng)接入連接Socket端口。僅用于acceptor正整數(shù),有效的、開(kāi)放的套接字端口-
SocketAcceptHost監(jiān)聽(tīng)接入連接的Socket服務(wù)的主機(jī)。如果不提供,acceptor將監(jiān)聽(tīng)所有網(wǎng)絡(luò)端口(0.0.0.0)有效的x.x.x.x格式IP地址0.0.0.0
SocketNodelay連接是否禁用Nagle算法。在[DEFAULT]配置節(jié)點(diǎn)定義。Y、NY

4.5 Storage

配置描述有效值默認(rèn)
PersistMessages如果設(shè)置為N,被不會(huì)保存消息。這樣將迫使quickfix總是發(fā)送GapFills,而不是重新發(fā)送消息。如果你知道你永遠(yuǎn)不需要重新發(fā)送消息,使用此配置。有用的市場(chǎng)數(shù)據(jù)流。Y、NY

4.6 File Storage

配置描述有效值默認(rèn)
FileStorePath存儲(chǔ)序列號(hào)和消息的文件目錄。有效的文件存儲(chǔ)目錄,必須有寫(xiě)入權(quán)限。-

4.7 Logging

配置描述有效值默認(rèn)
FileLogPath存儲(chǔ)日志的目錄。有效的文件存儲(chǔ)目錄,必須有寫(xiě)入權(quán)限。-

五、FIX開(kāi)發(fā)

5.1 FIX引擎

  • 官網(wǎng):FIX引擎(http://www.quickfixengine.org/)

github:QFJ GitHub Repository(https://github.com/quickfix-j/quickfixj)

5.2 DEMO

Acceptor 配置文件

# 定義會(huì)話(huà)的默認(rèn)配置(default節(jié)點(diǎn))
[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 配置文件

[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.*;
/**
 * 服務(wù)啟動(dòng)主類(lèi)(線程)
 */
public class FixServer {
    private static ThreadedSocketAcceptor acceptor = null;
    /**
     * 指定配置文件啟動(dòng)
     *
     * @param propFile
     * @throws ConfigError
     * @throws FieldConvertError
     */
    public FixServer(String propFile) throws ConfigError, FieldConvertError {
        // 設(shè)置配置文件
        SessionSettings settings = new SessionSettings(propFile);
        // 設(shè)置一個(gè)APPlication
        Application application = new FixServerApplication();
        /**
         *
         * quickfix.MessageStore 有2種實(shí)現(xiàn)。 quickfix.JdbcStore,quickfix.FileStore .
         * JdbcStoreFactory 負(fù)責(zé)創(chuàng)建JdbcStore , FileStoreFactory 負(fù)責(zé)創(chuàng)建FileStorequickfix
         * 默認(rèn)用文件存儲(chǔ),因?yàn)槲募鎯?chǔ)效率高。
         */
        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();
    }
    /**
     * 測(cè)試本地使用的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(" 服務(wù)器啟動(dòng)時(shí)候調(diào)用此方法創(chuàng)建");
    }
    @Override
    public void onLogon(SessionID sessionId) {
        System.out.println("客戶(hù)端登陸成功時(shí)候調(diào)用此方法");
    }
    @Override
    public void onLogout(SessionID sessionId) {
        System.out.println("客戶(hù)端斷開(kāi)連接時(shí)候調(diào)用此方法");
    }
    @Override
    public void toAdmin(Message message, SessionID sessionId) {
        System.out.println("發(fā)送會(huì)話(huà)消息時(shí)候調(diào)用此方法");
    }
    @Override
    public void toApp(Message message, SessionID sessionId) throws DoNotSend {
        System.out.println("發(fā)送業(yè)務(wù)消息時(shí)候調(diào)用此方法");
    }
    @Override
    public void fromAdmin(Message message, SessionID sessionId)
            throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
        System.out.println("接收會(huì)話(huà)類(lèi)型消息時(shí)調(diào)用此方法");
        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("接收業(yè)務(wù)消息時(shí)調(diào)用此方法");
        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);
    }
}

以上就是如何理解FIX協(xié)議的原理、消息格式及配置開(kāi)發(fā),小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

fix
AI