FIX API
[!NOTE] 此 API 只能用于现货 (
SPOT
) 交易所。
基本信息
FIX 连接需要 TLS 加密。请使用本地 TCP+TLS 连接或设置本地代理如 stunnel 来处理 TLS 加密。
FIX 会话仅支持 Ed25519 密钥。
关于如何设置 Ed25519 密钥对,请参 考 本教程。
FIX API 订单接入会话
- 端点为:
tcp+tls://fix-oe.binance.com:9000
- 支持下单,取消订单和查询当前限制使用情况。
- 支持接收账户的所有 ExecutionReport
<8>
和 List Status<N>
。 - 仅允许带有
FIX_API
的 API Key 连接。 - 关于 QuickFix 模式文件, 请点击 这里。
FIX API Drop Copy 会话
- 端点为:
tcp+tls://fix-dc.binance.com:9000
- 支持接收账户的所有 ExecutionReport
<8>
和 List Status<N>
。 - 仅允许连接带有
FIX_API
或FIX_API_READ_ONLY
的 API Key。 - 关于 QuickFix 模式文件, 请点击 这里。
FIX API Market Data 会话
- 端点为:
tcp+tls://fix-md.binance.com:9000
- 支持市场数据流和活动工具查询。
- 不支持下订单或取消订单。
- 仅允许连接带有“FIX_API”或“FIX_API_READ_ONLY”的 API 密钥。
关于 QuickFix 模式 (Schema) 文件, 请点击 这里。
FIX 连接需要 TLS 加密。请使用本地 TCP+TLS 连接或设置本地代理如 stunnel 来处理 TLS 加密。
FIX Market Data 的 QuickFix Schema 可以在 这里
API Key 权限
如果您需要使用 FIX API 的订单接入会话,您的 API key 必须配置 FIX_API
权限。
如果您需要使用 FIX API 的 Drop Copy 会话,您的 API key 必须配置 FIX_API_READ_ONLY
或 FIX_API
权限。
要访问 FIX Market Data 会话,您的 API 密钥必须配置为 FIX_API
或 FIX_API_READ_ONLY
权限
FIX 会话仅支持 Ed25519 密钥。
关于如何设置 Ed25519 密钥对,请参考 本教程。
关于消息处理顺序
初始消息 Logon<A>
中必需的 MessageHandling (25035)
字段被用于控制:是否在消息被撮合引擎处理前,需要重新排序消息。
UNORDERED(1)
允许不按顺序将来自客户端的消息发送到撮合引擎。SEQUENTIAL(2)
来自客户端的消息始终以MsgSeqNum(34)
中定义的顺序发送到撮合引擎。
[!TIP] 在有多个消息需要从客户端传输到服务器的情况时,
UNORDERED(1)
应该会提供更好的性能。
响应模式
默认情况下,所有并发订单录入会话都会接收到账户所有
成功的 ExecutionReport <8>
和 ListStatus <N>
消 息,
包括从其他 FIX 会话和通过非 FIX API 下达的订单。
用户可以在初始消息 Logon<A>
中使用 ResponseMode (25036)
字段来改变这种行为。
EVERYTHING(1)
: 默认模式。ONLY_ACKS(2)
: 无论操作成功还是失败,都只接收 ACK 消息。禁用ExecutionReport
推送。
如何签署 Logon<A>
请求
Logon<A>
消息用于验证您与 FIX API 的连接。
这条消息必须是客户端发送的第一条消息。
Username (553)
字段必须包含 API key。RawData (96)
字段必须包含使用 API key 生成的有效签名。
签名 payload 是一个文本字符串。该字符串通过按以下所列顺序去连接下列字段来构成, 并且以 SOH 字符作为分隔符:
MsgType (35)
SenderCompId (49)
TargetCompId (56)
MsgSeqNum (34)
SendingTime (52)
请使用您的密钥签署 payload。请使用 base64 对签名进行编码。
生成的文本字符串是 RawData (96)
字段的值。
以下是实现签名算法的 Python 代码示例:
import base64
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import load_pem_private_key
def logon_raw_data(private_key: Ed25519PrivateKey,
sender_comp_id: str,
target_comp_id: str,
msg_seq_num: str,
sending_time: str):
"""
Computes the value of RawData (96) field in Logon<A> message.
"""
payload = chr(1).join([
'A',
sender_comp_id,
target_comp_id,
msg_seq_num,
sending_time,
])
signature = private_key.sign(payload.encode('ASCII'))
return base64.b64encode(signature).decode('ASCII')
with open('private_key.pem', 'rb') as f:
private_key = load_pem_private_key(data=f.read(),
password=None)
raw_data = logon_raw_data(private_key,
sender_comp_id='5JQmUOsm',
target_comp_id='SPOT',
msg_seq_num='1',
sending_time='20240612-08:52:21.613')
以下值可用于验证签名计算实现的正确性:
字段 | 取值 |
---|---|
MsgType (35) | A |
SenderCompID (49) | EXAMPLE |
TargetCompID (56) | SPOT |
MsgSeqNum (34) | 1 |
SendingTime (52) | 20240627-11:17:25.223 |
示例计算中使用的 Ed25519 密钥如下所示:
[!CAUTION] 以下密钥仅用于示范说明目的。请务必不要在任何实际应用中使用该密钥,因为它不安全,可能会危及您的加密实现。请在实际使用中生成属于您自己的唯一且安全的密钥。
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIIJEYWtGBrhACmb9Dvy+qa8WEf0lQOl1s4CLIAB9m89u
-----END PRIVATE KEY-----
经过计算生成的签名:
4MHXelVVcpkdwuLbl6n73HQUXUf1dse2PCgT1DYqW9w8AVZ1RACFGM+5UdlGPrQHrgtS3CvsRURC1oj73j8gCA==
生成的 Logon <A>
消息:
8=FIX.4.4|9=247|35=A|34=1|49=EXAMPLE|52=20240627-11:17:25.223|56=SPOT|95=88|96=4MHXelVVcpkdwuLbl6n73HQUXUf1dse2PCgT1DYqW9w8AVZ1RACFGM+5UdlGPrQHrgtS3CvsRURC1oj73j8gCA==|98=0|108=30|141=Y|553=sBRXrJx2DsOraMXOaUovEhgVRcjOvCtQwnWj8VxkOh1xqboS02SPGfKi2h8spZJb|25035=2|10=227|
限制
消息限制
- 每个连接都有一个关于 可以发送到交易所的消息数量 的限制。
- 消息限制 不计算从接口发回到客户端的响应消息数量。
- 违反消息限制会立即导致 Logout
<5>
并断开连接。 - 要了解当前的限制和使用情况,请发送 LimitQuery
<XLQ>
消息。 接口将发送 LimitResponse<XLR>
消息作为响应,其中包含了有关订单速率限制和消息限制的信息。 - FIX 订单输入会话限制为每 10 秒 10,000 条消息。
- FIX 市场数据会话限制为每 60 秒 10,000 条消息
未成交订单计数
- 要了解您在特定时间间隔内下了多少订单,请发送 LimitQuery
<XLQ>
消息。 系统将发送一条 LimitResponse<XLR>
消息作为响应,其中会包含有关未成交订单计数和消息限制的信息。 - 请注意,如果您的订单一直顺利完成交易,您可以在 API 持续下订单。更多信息,请参见现货未成交订单计数规则。
- 如果您超过了未成交的订单计数限制,您的消息将被拒绝,并且信息将用该接口的拒绝消息格式传回给您。
- 未成交订单数量是按照每个账户来统计的。
连接限制
- 每个账户都有一个关于 可以同时建立的 TCP 连接数量 的限制。
- 当 TCP 连接关闭时,限制值会减少。如果限制值没有立即减少,请等待最长不超过2倍于在
HeartBtInt (108)
内所定义的时间。 比如说,如果HeartBtInt
的值为5, 那么请等待10秒钟。 - 违反限制时, Reject
<3>
消息会被发送给用户。该消息包含了有关违反连接限制和当前限制的信息。 - 对于订单接入会话,其限制为每个账户 5 个并发 TCP 连接。
- 对于 Drop Copy 会话,其限制为每个账户 10 个并发 TCP 连接。
- 对于市场数据会话,每个账户的并发 TCP 连接数限制为 100 个。
错误处理
包含句法错误,缺少必填字段,或引用未知交易对的客户端消息将被服务器拒绝,并返回 Reject <3>
消息。
如果有效消息无法被处理并被拒绝,服务器将发送相应的拒绝响应。 请参阅各个消息的相关文档以了解可能会发生的响应。
请参阅响应中的 Text (58)
和 ErrorCode (25016)
字段以了解拒绝原因。
错误代码列表可以在 错误代码 页面找到。
类型
仅支持可打印的 ASCII 字符和 SOH。
类型 | 描述 |
---|---|
BOOLEAN | Enum:Y 或 N . |
CHAR | 单个字符。 |
INT | 有符号的 64 位整数。 |
LENGTH | 无符号的 64 位整数。 |
NUMINGROUP | 无符号的 64 位整数。 |
PRICE | 定点数。精度取决于 symbol 定义。 |
QTY | 定点数。精度取决于 symbol 定义。 |
SEQNUM | 无符号的 64 位整数。 |
STRING | 可打印的 ASCII 字符串。 |
UTCTIMESTAMP | 表示 UTC 日期时间的字符串。 |
支持的 UTCTIMESTAMP
格式:
20011217-09:30:47
- 秒20011217-09:30:47.123
- 毫秒20011217-09:30:47.123456
- 微秒(用于来自交易所的消息)
客户端订单 ID 字段必须符合正则表达式 ^[a-zA-Z0-9-_]{1,36}$
:
ClOrdID (11)
OrigClOrdID (41)
MDReqID (262)
ClListID (25014)
OrigClListID (25015)
CancelClOrdID (25034)
消息组件
在示例消息中, |
字符用于表示 SOH 字符:
8=FIX.4.4|9=113|35=A|34=1|49=SPOT|52=20240612-08:52:21.636837|56=5JQmUOsm|98=0|108=30|25037=4392a152-3481-4499-921a-6d42c50702e2|10=051|
Header
出现在每条消息的开头。
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
8 | BeginString | STRING | Y | 始终为 FIX.4.4 。 必须是消息的第一个字段。 |
9 | BodyLength | LENGTH | Y | 消息长度(以字节为单位)。 必须是消息的第二个字段。 |
35 | MsgType | STRING | Y | 必须是消息的第三个字段。 可能的值: 0 - HEARTBEAT 1 - TEST_REQUEST 3 - REJECT 5 - LOGOUT 8 - EXECUTION_REPORT 9 - ORDER_CANCEL_REJECT A - LOGON D - NEW_ORDER_SINGLE E - NEW_ORDER_LIST F - ORDER_CANCEL_REQUEST N - LIST_STATUS q - ORDER_MASS_CANCEL_REQUEST r - ORDER_MASS_CANCEL_REPORT XCN - ORDER_CANCEL_REQUEST_AND_NEW_ORDER_SINGLE XLQ - LIMIT_QUERY XLR - LIMIT_RESPONSE B - NEWS x - INSTRUMENT_LIST_REQUEST y - INSTRUMENT_LIST V - MARKET_DATA_REQUEST Y - MARKET_DATA_REQUEST_REJECT W - MARKET_DATA_SNAPSHOT X - MARKET_DATA_INCREMENTAL_REFRESH |
49 | SenderCompID | STRING | Y | 在账户的活动会话中必须是独特的。 必须使用正则表达式: ^[a-zA-Z0-9-_]{1,8}$ |
56 | TargetCompID | STRING | Y | 在客户端的消息中必须设置为SPOT 。 |
34 | MsgSeqNum | SEQNUM | Y | 整数消息序列号。 会导致间隙的值将被拒绝。 |
52 | SendingTime | UTCTIMESTAMP | Y | 消息传输时间(始终以 UTC 表示)。 |
25000 | RecvWindow | INT | N | 在SendingTime (52) 后,用于标识请求有效时间的毫秒数。 在 Logon <A> 中默认为 5000 毫秒,最大值为 60000 毫秒。 |
Trailer
出现在每条消息的末尾。
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
10 | CheckSum | STRING | Y | 始终为3个字符的数字字符串。其取值是通过对消息中每个前导字符的 ASCII 值进行求和计算得出的,其中包括 start-of-header(SOH)。 结果总和除以 256,余数形成 CheckSum 值。 为保持固定长度,CheckSum 字段采用右对齐并按需要进行零填充。 |
Administrative Messages
Heartbeat <0>
如果在心跳间隔(Logon<A>
中的 HeartBtInt (108)
)的期间没有传出流量,则由服务器发送。
由客户端发送则用于指示会话正常。
由客户端或服务器发送,用于给予 TestRequest<1>
消息有关响应。
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
112 | TestReqID | STRING | N | 当 Heartbeat<35> 作为对 TestRequest<1> 的响应发送时,必须镜像 TestRequest<1> 中的值。 |
TestRequest <1>
如果在心跳间隔(Logon<A>
中的 HeartBtInt (108)
)的期间没有传入流 量,则由服务器发送。
由客户端发送用于请求 Heartbeat<0>
响应。
[!NOTE] 如果客户端未能在超时范围内发送带有正确
TestReqID (112)
的 Heartbeat<0>
来响应 TestRequest<1>
,其连接将被断开。
Tag | 名称 | 类型 | 必填 | 描述 |
---|---|---|---|---|
112 | TestReqID | STRING | Y | 任意字符串,必须包含在 Heartbeat<0> 响应中。 |
Reject <3>
由服务器发送,用以响应无法处理的无效消息。
如果无法接受新连接,则由服务器发送。 请参阅 Connection Limits。
请参阅 Text (58)
和 ErrorCode (25016)
字段以了解拒绝原因。
Tag | 名称 | 类型 | 必填 | 描述 |
---|---|---|---|---|
45 | RefSeqNum | INT | N | 导致此 Reject<3> 发送的被拒绝消息的 MsgSeqNum (34) 。 |
371 | RefTagID | INT | N | 如果存在,标识直接导致此 Reject<3> 消息发送的字段。 |
372 | RefMsgType | STRING | N | 导致此 Reject<3> 发送的被拒绝消息的 MsgType (35) 。 |
373 | SessionRejectReason | INT | N | 拒绝的原因,可以是以下值之一。 通常伴随附加的文字描述 可能的值: 0 - INVALID_TAG_NUMBER 1 - REQUIRED_TAG_MISSING 2 - TAG_NOT_DEFINED_FOR_THIS_MESSAGE_TYPE 3 - UNDEFINED_TAG 5 - VALUE_IS_INCORRECT 6 - INCORRECT_DATA_FORMAT_FOR_VALUE 8 - SIGNATURE_PROBLEM 10 - SENDINGTIME_ACCURACY_PROBLEM 12 - XML_VALIDATION_ERROR 13 - TAG_APPEARS_MORE_THAN_ONCE 14 - TAG_SPECIFIED_OUT_OF_REQUIRED_ORDER 15 - REPEATING_GROUP_FIELDS_OUT_OF_ORDER 16 - INCORRECT_NUMINGROUP_COUNT_FOR_REPEATING_GROUP99 - OTHER |
25016 | ErrorCode | INT | N | API 错误代码(参见 错误代码)。 |
58 | Text | STRING | N | 人类可读的错误信息。 |
Logon<A>
由客户端发送,用以验证连接。
Logon<A>
必须是客户端发送的第一条消息。
由服务器发送,用以响应成功的登录。
[!NOTE] Logon
<A>
在整个会话期间只能发送一次。
Logon Request
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
98 | EncryptMethod | INT | Y | 必须为 0 。 |
108 | HeartBtInt | INT | Y | 必须在 [5, 60] 范围内。Heartbeat 间隔(秒)。 |
95 | RawDataLength | LENGTH | Y | 紧随此字段之后的 RawData (96) 字段的长度。 |
96 | RawData | DATA | Y | 签名。 如何签署 Logon<A> 请求。 |
141 | ResetSeqNumFlag | BOOLEAN | Y | 必须为 Y 。 |
553 | Username | STRING | Y | API key。仅支持 Ed25519 API keys。 |
25035 | MessageHandling | INT | Y | 可能的值: 1 - UNORDERED 2 - SEQUENTIAL 请参阅 关于消息处理顺序 了解更多信息。 |
25036 | ResponseMode | INT | N | 请参阅 响应模式。 |
9406 | DropCopyFlag | BOOLEAN | N | 登录到 Drop Copy 会话时,必须设置为"Y"。 |
示例消息:
8=FIX.4.4|9=248|35=A|34=1|49=5JQmUOsm|52=20240612-08:52:21.613|56=SPOT|95=88|96=KhJLbZqADWknfTAcp0ZjyNz36Kxa4ffvpNf9nTIc+K5l35h+vA1vzDRvLAEQckyl6VDOwJ53NOBnmmRYxQvQBQ==|98=0|108=30|141=Y|553=W5rcOD30c0gT4jHK8oX5d5NbzWoa0k4SFVoTHIFNJVZ3NuRpYb6ZyJznj8THyx5d|25035=1|10=000|
Logon Response
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
98 | EncryptMethod | INT | Y | 始终为 0 。 |
108 | HeartBtInt | INT | Y | 镜像 Logon 请求中的值。 |
25037 | UUID | STRING | Y | 提供请求服务的 FIX API 的 UUID。 |
示例消息:
8=FIX.4.4|9=113|35=A|34=1|49=SPOT|52=20240612-08:52:21.636837|56=5JQmUOsm|98=0|108=30|25037=4392a152-3481-4499-921a-6d42c50702e2|10=051|
Logout <5>
发送此消息以启动关闭连接的过程,并对 Logout 进行响应。
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
58 | Text | STRING | N |
示例消息:
Logout 请求
8=FIX.4.4|9=55|35=5|34=3|49=GhQHzrLR|52=20240611-09:44:25.543|56=SPOT|10=249|
Logout 响应
8=FIX.4.4|9=84|35=5|34=4|49=SPOT|52=20240611-09:44:25.544001|56=GhQHzrLR|58=Logout acknowledgment.|10=212|
News <B>
当连接即将关闭时,由服务器发送。
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
148 | Headline | STRING | Y |
示例消息:
8=FIX.4.4|9=0000113|35=B|49=SPOT|56=OE|34=4|52=20240924-21:07:35.773537|148=Your connection is about to be closed. Please reconnect.|10=165|
Application Messages
下单消息
[!NOTE] 以下消息只能用于 FIX 订单接入会话和 FIX Drop Copy 会话
NewOrderSingle<D>
由客户端发送,用以提交新订单并进行执行。
请参阅 支持的订单类型 了解支持的字段组合。
[!NOTE] 许多字段会根据订单类型变为必填。 请参阅 支持的订单类型。
Tag | 名称 | 类型 | 是否必须 | 描述 |
---|---|---|---|---|
11 | ClOrdID | STRING | Y | 分配给订单的 ClOrdID 。 |
38 | OrderQty | QTY | N | 订单数量 |
40 | OrdType | CHAR | Y | 请参阅 表格 了解支持的订单类型和所需字段。 可能的值: 1 - MARKET 2 - LIMIT 3 - STOP 4 - STOP_LIMIT |
18 | ExecInst | CHAR | N | 可能的值: 6 - PARTICIPATE_DONT_INITIATE |
44 | Price | PRICE | N | 订单价格 |
54 | Side | CHAR | Y | 订单方向。 可能的值: 1 - BUY 2 - SELL |
55 | Symbol | STRING | Y | 下单的交易对。 |
59 | TimeInForce | CHAR | N | 可能的值: 1 - GOOD_TILL_CANCEL 3 - IMMEDIATE_OR_CANCEL 4 - FILL_OR_KILL |
111 | MaxFloor | QTY | N | 用于冰山订单,指定订单在订单簿上的可见数量。 |
152 | CashOrderQty | QTY | N | 以报价资产单位指定的订单数量,用于反向市场订单。 |
847 | TargetStrategy | INT | N | 该值不能小于 1000000 。 |
7940 | StrategyID | INT | N | |
25001 | SelfTradePreventionMode | CHAR | N | 可能的值: 1 - NONE 2 - EXPIRE_TAKER 3 - EXPIRE_MAKER 4 - EXPIRE_BOTH |
1100 | TriggerType | CHAR | N | 可能的值: 4 - PRICE_MOVEMENT |
1101 | TriggerAction | CHAR | N | 可能的值: 1 - ACTIVATE |
1102 | TriggerPrice | PRICE | N | 止盈止损订单的激活价格。请参阅 表格 |
1107 | TriggerPriceType | CHAR | N | 可能的值: 2 - LAST_TRADE |
1109 | TriggerPriceDirection | CHAR | N | 用于区分 StopLoss 和 TakeProfit 订单。请参阅 表格。 可能的值: U - TRIGGER_IF_THE_PRICE_OF_THE_SPECIFIED_TYPE_GOES_UP_TO_OR_THROUGH_THE_SPECIFIED_TRIGGER_PRICE D - TRIGGER_IF_THE_PRICE_OF_THE_SPECIFIED_TYPE_GOES_DOWN_TO_OR_THROUGH_THE_SPECIFIED_TRIGGER_PRICE |
25009 | TriggerTrailingDeltaBips | INT | N | 提供以创建追踪订单。 |
25032 | SOR | BOOLEAN | N | 是否为此订单激活 SOR。 |
示例消息:
8=FIX.4.4|9=114|35=D|34=2|49=qNXO12fH|52=20240611-09:01:46.228|56=SPOT|11=1718096506197867067|38=5|40=2|44=10|54=1|55=LTCBNB|59=4|10=016|
响应:
- 如果订单被接受, ExecutionReport
<8>
的ExecType (150)
值为NEW (0)
。 - 如果订单被拒绝, ExecutionReport
<8>
的ExecType (150)
值为REJECTED (8)
。 - 如果消息被拒绝,则为 Reject
<3>
。