FIX 会话¶
来源状态
正文摘录自 postman/Polaris-FIX-Document.postman_collection.json
(Pepperstone Crypto FIX API 机构接入指南)。
本地 ptrader-fix-server 检出目前仅有 README(无 src/)。
字段表在源码核验前视为已发布的客户端契约 —
见 待确认清单。
中英对照
下列协议术语、Tag 表与报文示例保留英文原文(FIX 线路契约)。导航与说明使用中文。
FIX session¶
FIX API¶
Pepperstone Crypto exposes a FIX 5.0 SP2 (over FIXT.1.1) gateway for institutional spot trading. This guide describes the wire contract clients must implement.
FIXT.1.1 FIX 5.0 SP2 Spot Institutional
Overview¶
The gateway is a FIX acceptor. Your side is the initiator: you open the TCP connection and send the first Logon (35=A). The gateway terminates the FIX session, validates the message dictionary, and forwards application traffic to the spot matching engine and market-data buses.
Supported message types are listed below. Anything not in this table is either rejected at the session layer (35=3) or silently ignored.
| Direction | MsgType | Name | Purpose |
|---|---|---|---|
| Inbound | A |
Logon | Establish session; carries API key. |
| Inbound | 0 |
Heartbeat | Standard idle heartbeat. |
| Inbound | 1 |
TestRequest | Liveness probe. |
| Inbound | 2 |
ResendRequest | Gap fill from persisted store. |
| Inbound | 3 |
Reject | Client-side session-level reject; server logs and ignores (no retransmit). |
| Inbound | 4 |
SequenceReset | Gap-fill or admin reset; handled natively by QuickFIX/J. |
| Inbound | 5 |
Logout | Ends session; triggers cancel-on-logout. |
| Inbound | D |
NewOrderSingle | Place a MARKET or LIMIT order. |
| Inbound | F |
OrderCancelRequest | Cancel a single working order. |
| Inbound | q |
OrderMassCancelRequest | Cancel all working orders for a symbol. |
| Inbound | V |
MarketDataRequest | Subscribe / snapshot / unsubscribe depth. |
| Inbound | x |
SecurityListRequest | List the active symbol catalog. |
| Outbound | 3 |
Reject | Session-level dictionary reject. |
| Outbound | 4 |
SequenceReset | Gap-fill (skip admin msgs during resend) or admin reset. |
| Outbound | 8 |
ExecutionReport | Order lifecycle events. |
| Outbound | 9 |
OrderCancelReject | Cancel not routable at the gateway. |
| Outbound | j |
BusinessMessageReject | Business-layer reject (e.g. rate limit). |
| Outbound | r |
OrderMassCancelReport | ACK of mass-cancel request. |
| Outbound | y |
SecurityList | Symbol catalog response. |
| Outbound | W |
MarketDataSnapshotFullRefresh | Full top-N book snapshot. |
| Outbound | X |
MarketDataIncrementalRefresh | Per-tick top-N rebroadcast + trades. |
| Outbound | Y |
MarketDataRequestReject | Business-layer reject for MD subscription. |
Connection¶
The gateway is exposed over plain TCP. TLS is terminated at the network edge; the exact endpoints for each environment (UAT / production) are delivered as part of your onboarding package.
Connection parameters¶
| Setting | Value | Notes |
|---|---|---|
| BeginString (8) | FIXT.1.1 |
Session-layer dictionary. |
| DefaultApplVerID (1137) | 9 (FIX.5.0SP2) |
Application-layer dictionary. |
| Server SenderCompID (49) / your TargetCompID (56) | PtradeFIXServer-<SITE> |
Site suffix is environment-specific (e.g. PtradeFIXServer-AU). Exact value provided at onboarding. |
| Your SenderCompID (49) / server TargetCompID (56) | Allocated per client | Provisioned during onboarding. |
| EncryptMethod (98) | 0 (None) |
Confidentiality is handled at the transport layer. |
| HeartBtInt (108) | 30s recommended |
The gateway honours whatever value you send on Logon. |
| Trading window | 24 × 7 UTC | Maintenance windows announced separately. |
Session lifecycle¶
Logon (35=A)¶
The first message after the TCP handshake must be Logon. The gateway checks:
Username (553)is present and non-empty — it carries your API key.- The API key is validated against the central authentication service. If it is disabled, not institutional, or unknown, the Logon is rejected.
- If
HeartBtInt (108)is supplied, that value is used for the session. - If
ResetSeqNumFlag (141) = Yis supplied, sequence numbers are reset both ways.
No password is transmitted on the FIX wire. Your API key is bound to the trusted source IP allocated at onboarding.
Inbound · Logon
8=FIXT.1.1|9=...|35=A|34=1|49=CLIENT|56=PtradeFIXServer-AU|52=20260515-09:00:00.000|
98=0|108=30|141=Y|553=<your_api_key>|1137=9|10=...
Outbound · Logon (accepted)
8=FIXT.1.1|9=...|35=A|34=1|49=PtradeFIXServer-AU|56=CLIENT|52=20260515-09:00:00.100|
98=0|108=30|1137=9|10=...
Heartbeat & TestRequest¶
Standard FIX semantics. When the link is idle for longer than the negotiated HeartBtInt, both peers exchange Heartbeat (35=0). Either side may send a TestRequest (35=1) with a TestReqID (112); the counterparty must reply with a Heartbeat echoing the same 112.
Timing rules (enforced by QuickFIX/J):
- If the link is idle for
HeartBtIntseconds, send an unsolicitedHeartbeat. - If nothing is received for
HeartBtInt × 1.2seconds, the engine sends aTestRequest. - If the
TestRequestis not answered within anotherHeartBtInt × 1.2seconds, the session is dropped as unresponsive.
Outbound · Heartbeat (idle)
Inbound · TestRequest
8=FIXT.1.1|9=…|35=1|34=101|49=CLIENT|56=PtradeFIXServer-AU|
52=20260515-09:00:36.000|112=probe-42|10=…
Outbound · Heartbeat (TestRequest response)
8=FIXT.1.1|9=…|35=0|34=43|49=PtradeFIXServer-AU|56=CLIENT|
52=20260515-09:00:36.001|112=probe-42|10=…
ResendRequest (35=2)¶
Because the gateway persists messages (PersistMessages=Y), standard gap-fill / resend is fully supported by the QuickFIX/J engine — the application layer is not involved. BeginSeqNo (7) is the first missing sequence number; EndSeqNo (16) = 0 means "up to infinity".
On receiving a ResendRequest, the gateway replays application messages from disk. Session-level admin messages (Heartbeat, TestRequest, ResendRequest itself, SequenceReset, Logon, Logout) are not replayed — the engine skips them by emitting SequenceReset (35=4) with GapFillFlag (123) = Y covering that range.
Replayed application messages carry PossDupFlag (43) = Y and a OrigSendingTime (122) equal to the original transmission time; treat them as idempotent by MsgSeqNum (34).
Scenario. Client reconnects and continues at 34=210. The gateway's next expected inbound is 200, so it requests messages [200, ∞). Messages 200–204 are session-admin (skipped via gap-fill); 205–209 are ExecutionReports that get replayed as PossDupFlag=Y.
Outbound · ResendRequest
Inbound · SequenceReset · gap-fill (client skips admin msgs 200–204)
8=FIXT.1.1|9=…|35=4|34=200|49=CLIENT|56=PtradeFIXServer-AU|
52=20260515-09:05:00.100|43=Y|123=Y|36=205|10=…
Inbound · ExecutionReport (replayed, PossDupFlag=Y)
8=FIXT.1.1|9=…|35=8|34=205|49=CLIENT|56=PtradeFIXServer-AU|
52=20260515-09:05:00.200|43=Y|122=20260515-09:03:12.500|
37=1234567|11=cli-10001|55=BTC_USDT|54=1|38=0.50|44=62000.00|
150=F|39=2|14=0.50|151=0|6=62000.00|31=62000.00|32=0.50|60=20260515-09:03:12.500|10=…
SequenceReset (35=4)¶
Handled natively by the QuickFIX/J session layer. There are two operating modes, distinguished by GapFillFlag (123).
| 123 | Mode | Behaviour |
|---|---|---|
Y |
Gap-fill | Emitted as part of a ResendRequest reply to skip admin / non-replayable messages. Sequence-number checking applies: if 34 is out of order, the engine treats it as a real gap-fill within the resend window. This is the safe mode you will always see from the gateway. |
N / omitted |
Admin reset | Dangerous. The receiver's next-expected inbound sequence number is force-set to NewSeqNo (36) regardless of gaps. Prefer resetting via Logon with ResetSeqNumFlag (141) = Y; only fall back to admin 35=4 when an operator explicitly coordinates it. |
Fields¶
| Tag | Field | Req? | Notes |
|---|---|---|---|
36 |
NewSeqNo | Y | Next expected inbound sequence number on the receiver. |
123 |
GapFillFlag | N | Y = gap-fill (safe); N / omitted = admin reset. |
43 |
PossDupFlag | N | Always Y when the message is a gap-fill for a resend window. |
Scenario A · gap-fill. During a resend, the gateway needs to skip admin messages 34=200..204 so that the client's next inbound expectation lands on 205. It sends a single SequenceReset with GapFillFlag=Y, MsgSeqNum=200, NewSeqNo=205.
Inbound · SequenceReset · gap-fill
8=FIXT.1.1|9=…|35=4|34=200|49=CLIENT|56=PtradeFIXServer-AU|
52=20260515-09:05:00.100|43=Y|123=Y|36=205|10=…
Scenario B · admin reset. An operator has coordinated a manual sequence reset on the client side. The client sends a SequenceReset with GapFillFlag=N to force the gateway's next expected inbound to NewSeqNo=1000. Because this is an admin message, MsgSeqNum (34) is ignored — the gateway never treats it as a real gap.
Outbound · SequenceReset · admin reset (rarely used)
8=FIXT.1.1|9=…|35=4|34=999|49=PtradeFIXServer-AU|56=CLIENT|
52=20260515-10:00:00.000|123=N|36=1000|10=…
Reject (35=3) — session-level¶
Emitted by the QuickFIX/J engine before a message reaches any application handler when it fails dictionary validation. The gateway runs with strict validation (ValidateIncomingMessage=Y, AllowUnknownMsgFields=N), so anything that violates the FIX 5.0 SP2 dictionary is rejected at the session layer with a MsgSeqNum that still counts. A full breakdown of SessionRejectReason (373) values is in the Reject codes reference.
Reject messages carry:
RefSeqNum (45)— the34of the offending messageRefMsgType (372)— its35=value (when identifiable)RefTagID (371)— the tag that failed (when applicable)SessionRejectReason (373)— machine-readable reason codeText (58)— human-readable diagnostic
The reciprocal direction is also supported: if the gateway ever sends you a malformed message, you may reply with your own 35=3. The server logs and ignores it — it will not retransmit that message.
Outbound · Reject (unknown tag)
8=FIXT.1.1|9=…|35=3|34=42|49=PtradeFIXServer-AU|56=CLIENT|
52=20260515-09:00:00.000|45=17|372=D|371=9999|
373=2|58=Tag not defined for this message type: 9999|10=…
Logout (35=5) — cancel-on-logout¶
IMPORTANT: When you send
Logout, the gateway sends a cancel to the matching engine for every working order tracked on that session, then closes the socket. If you want resting orders to survive a reconnect, drop the TCP connection — do not send Logout.
The actual ExecutionReport (ExecType=Canceled) is produced by the matching engine and may arrive after the FIX session closes. Reconcile via your back-office channel after reconnect.