FIX API
[!NOTE] 此 API 只能用于现货 (
SPOT) 交易所。
一般 API 信息
- FIX 连接需要 TLS 加密。请使用本地 TCP+TLS 连接或设置本地代理如 stunnel 来处理 TLS 加密。
- API 处理请求的超时时间为 10 秒。如果撮合引擎的响应时间超过此时间,API 将返回 “Timeout waiting for response from backend server. Send status unknown; execution status unknown.”。(-1007 超时)
- 这并不总是意味着该请求在撮合引擎中失败。
- 如果请求状态未显示在 WebSocket 账户接口 中,请执行 API 查询以获取其状态。
- 如果您的请求包含非 ASCII 字符的交易对名称,那么响应中可能包含以 UTF-8 编码的非 ASCII 字符。
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 可以在 这里
FIX 连接生命周期
- 所有 FIX API 会话将尽最大努力,尽可能长时间地保持开放状态。
- 没有最短连接时间保证,服务器可能随时进入维护状态。
- 当服务器进入维护状态时,系统将会向客户端每隔 10 秒发送一条 News
<B>消息,并持续 10 分钟,以提示客户端重新连接。收到此消息后,客户端应建立新会话并关闭旧会话。如果客户端未在规定的时间范围内关闭旧连接,那么服务器会将其注销并关闭会话。
- 当服务器进入维护状态时,系统将会向客户端每隔 10 秒发送一条 News
- 连接后,客户端必须发送 Logon
<A>请求。有关详情,请参阅 如何签署登录请求。 - 客户端应在断开连接之前发送 Logout
<5>消息来关闭会话。未能发送注销消息将导致在 2xHeartInt (108)定义的时间间隔内无法将会话的SenderCompID (49)用于新会话的建立。 - 系统允许在登录过程中协商
HeartInt (108)值。可接受值的范围为 5 到 60 秒。- 如果服务器在
HeartInt (108)间隔内没有发送任何消息,将发送 HeartBeat<0>。 - 如果服务器在
HeartInt (108)间隔内没有收到任何消息,将发送 TestRequest<1>。如果服务器在HeartInt (108)秒内没有收到来自客户端的包含预期TestReqID (112)的 HeartBeat<0>消息,服务器将发送 Logout<5>消息并关闭连接。 - 如果客户端在
HeartInt (108)间隔内未收到任何消息,那么客户端应负责发送 TestRequest<1>消息以确保连接正常。收到这样的 TestRequest<1>后,服务器会发送包含预期TestReqID (112)的 HeartBeat<0>消息来进行响应。如果客户端在HeartInt (108)间隔内没有收到服务器的响应,那么客户端应关闭现有的会话和连接,并且建立新的会话和连接。
- 如果服务器在
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) 顺序发送到撮合引擎。 |
在所有模式下,客户端的 MsgSeqNum (34) 必须单调递增,即每条后续消息的序列号都比前一条消息正好大 1。
[!TIP] 在有多个消息需要从客户端传输到服务器的情况时,
UNORDERED(1)应该会提供更好的性能。
响应模式
默认情况下,所有并发订单录入会话都会接收到账户所有
成功的 ExecutionReport <8> 和 ListStatus <N> 消息,
包括从其他 FIX 会话和通过非 FIX API 下达的订单。
用户可以在初始消息 Logon<A> 中使用 ResponseMode (25036) 字段来改变这种行为。
EVERYTHING(1): 默认模式。ONLY_ACKS(2): 无论操作成功还是失败,都只接收 ACK 消息。禁用ExecutionReport推送。
时间同步安全
- 所有请求都需要一个
SendingTime(52)字段,该字段应为当前时间戳。 - 另有一个可选字段
RecvWindow(25000),用以指定请求的有效期(以毫秒为单位)。RecvWindow(25000)扩展为三位小数(例如 6000.346),以便可以指定微秒。- 如果未指定
RecvWindow(25000),则仅对 Logon<A>请求默认为 5000 毫秒。对于其他请求,如果未设置,则不会执行 RecvWindow 检查。 RecvWindow(25000)的最大有效时间为 60000 毫秒。
- 请求处理逻辑如下:
serverTime = getCurrentTime()
if (SendingTime < (serverTime + 1 second) && (serverTime - SendingTime) <= RecvWindow) {
// 开始处理请求
serverTime = getCurrentTime()
if (serverTime - SendingTime) <= RecvWindow {
// 将请求转发到撮合引擎
} else {
// 拒绝请求
}
// 结束处理请求
} else {
// 拒绝请求
}
如何签署 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 API 订单输入会话的限制为每 10 秒 10,000 条消息。
- FIX Drop Copy 会话的限制为每 60 秒 60 条消息。
- FIX Market Data 会话的限制为每 60 秒 2000 条消息。
未成交订单计数
- 要了解您在特定时间间隔内下了多少订单,请发送 LimitQuery
<XLQ>消息。 系统将发送一条 LimitResponse<XLR>消息作为响应,其中会包含有关未成交订单计数和消息限制的信息。 - 请注意,如果您的订单一直顺利完成交易,您可以在 API 持续下订单。更多信息,请参见现货未成交订单计数规则。
- 如果您超过了未成交的订单计数限制,您的消息将被拒绝,并且信息将用该接口的拒绝消息格式传回给您。
- 未成交订单数量是按照每个账户来统计的。
连接限制
- 每个账户都有一个关于 可以同时建立的 TCP 连接数量 的限制。
- 当 TCP 连接关闭时,限制值会减少。如果限制值没有立即减少,请等待最长不超过2倍于在
HeartBtInt (108)内所定义的时间。 比如说,如果HeartBtInt的值为5, 那么请等待10秒钟。 - 违反限制时, Reject
<3>消息会被发送给用户。该消息包含了有关违反连接限制和当前限制的信息。 - FIX 订单接入会话限制:
- 在 30 秒内 15 次连接尝试的限制
- 每个账户 最多 10 个并发 TCP 连接的限制
- FIX Drop Copy 会话限制:
- 在 30 秒内 15 次连接尝试的限制
- 每个账户 10 个并发 TCP 连接的限制
- FIX Market Data 会话限制:
- 在 300 秒内 300 次连接尝试的限制
- 每个账户 100 个并发 TCP 连接的限制
- 单一连接最多能监听 1000 个数据流
错误处理
包含句法错误,缺少必填字段,或引用未知交易对的客户端消息将被服务器拒绝,并返回 Reject <3> 消息。
如果有效消息无法被处理并被拒绝,服务器将发送相应的拒绝响应。 请参阅各个消息的相关文档以了解可能会发生的响应。
请参阅响应中的 Text (58) 和 ErrorCode (25016) 字段以了解拒绝原因。
错误代码列表可以在 错误代码 页面找到。
类型
仅支持可打印的 ASCII 字符和 SOH。
| 类型 | 描述 |
|---|---|
BOOLEAN | Enum:Y 或 N. |
CHAR | 单个字符。 |
INT | 有符号的 64 位整数。 |
LENGTH | 无符号的 64 位整数。 |
NUMINGROUP | 无符号的 64 位整数。 |
PRICE | 定点数。精度取决于 symbol 定义。 |
QTY | 定点数。精度取决于 symbol 定义。 |
SEQNUM | 无符号的 32 位整数。达到最大值 4,294,967,295 后会归 0,然后重新开始计数。 |
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 XAK - ORDER_AMEND_KEEP_PRIORITY_REQUEST XAR - ORDER_AMEND_REJECT |
| 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 | FLOAT | N | 在SendingTime (52) 后,用于标识请求有效时间的毫秒数。 在 Logon <A> 中默认为 5000 毫秒,最大值为 60000 毫秒。 支持最多三位小数的精度(例如 6000.346),以便可以指定微秒。 |