Since updated the 2nd paragraph to clarify the LOGON sequence details as pointed out in one of the comments below
I'm relatively new to FIX and I'm spiking the use of QuickFix/Go to manage FIX sessions with Coinbase Exchange. These are long lasting sessions. ResetOnLogon
, ResetOnDisconnect
, and ResetOnLogout
configuration settings are all set to 'N' so that interrupted sessions will pick up where they left off barring the mandatory Logout by Coinbase at 1PM ET every Saturday.
Coinbase's LOGON response will always return MsgSeqNum = 1 regardless of ResetSeqNumFlag=N in the LOGON request from us. This is fine for the first LOGON of a session as 1 is the expected target message sequence number for our initiator. However, if I stop the session and restart QuickFIX/Go rejects the LOGON response received from Coinbase saying the message number is too low, which seems correct but keeps the session from being established.
The only way I've been able to get around this is to manually set the next target message sequence number in the FromAdmin
handler before QuickFix/Go attempts to validate sequence nubmers:
func (a *App) FromAdmin(msg *quickfix.Message, sessionID quickfix.SessionID) (reject quickfix.MessageRejectError) {
if msg.IsMsgTypeOf(string(enum.MsgType_LOGON)) {
// THIS FEELS WRONG
msgNum, _ := msg.Header.GetInt(tag.MsgSeqNum)
_ = quickfix.SetNextTargetMsgSeqNum(sessionID, msgNum)
} else if msg.IsMsgTypeOf(string(enum.MsgType_SEQUENCE_RESET)) && !msg.Header.Has(tag.PossDupFlag) {
// SHOULD I BE CHECKING AGAINST THE INITIAL SEQ NUMBERS MYSELF HERE???
} else {
fmt.Println("FromAdmin: Received Admin message", msg.String())
}
return
}
After that, Coinbase seems to honor the ResetSeqNumFlag=N
flag of this second successful (albeit forced on my end) LOGON
with a SequenceReset to the target sequence number from the previous session, which QuickFIX/Go happily accepts and the session moves along.
I feel fairly certain that I shouldn't naively reset the TSN to 1 just to satisfy the LOGON sequence mandated by the exchange. I'm also unsure how to properly tell QuickFIX/Go what the TSN actually should be during/after the sequence reset callback, such that gap detection can kick in.
Is QuickFIX/Go just not compatible with Coinbase's setup?
I've included some logs of this below. Any insight would be greatly appreciated.
Initial Session humming along with a couple heartbeats and a logon
.
.
.
2024/11/19 04:25:15.329915 8=FIXT.1.1|9=101|35=0|49=Coinbase|56=myuser|34=11|50=TEST|52=20241119-04:25:15.433499|369=9|10=047|
2024/11/19 04:25:17.380701 8=FIXT.1.1|9=84|35=0|34=10|49=myuser|52=20241119-04:25:17.363|56=Coinbase|10=106|
Simulated network outage via wifi disconnect so my initiator tries a TEST request
2024/11/19 04:25:27.356721 8=FIXT.1.1|9=93|35=1|34=11|49=myuser|52=20241119-04:25:27.337|56=Coinbase|112=TEST|10=128|
network comes back up we LOGON again; The acceptor's response is accepted by the QuickFix/Go initiator but only because of my forced target number change in the FromAdmin handler
without it we would get the message too low error
2024/11/19 04:27:39.715256 8=FIXT.1.1|9=216|35=A|34=12|49=myuser|52=20241119-04:27:39.695|56=Coinbase|95=44|96=yRsmjXXh4DFH4CKX7dpR/0eG1x3/YYJbQsZ8AMuzpzg=|98=0|108=10|141=N|553=myuser|554=mypassword|1137=9|10=020|
2024/11/19 04:27:39.793277 8=FIXT.1.1|9=126|35=A|49=Coinbase|56=myuser|34=1|50=TEST|52=20241119-04:27:39.893965|369=12|98=0|108=10|141=N|1137=9|10=204|
acceptor immediately sends a sequence reset to 16, a test request, the QuickFix/Go initiator updates the sequence number to 16 and then more heartbeating
2024/11/19 04:27:39.806345 8=FIXT.1.1|9=113|35=4|49=Coinbase|56=myuser|34=2|50=TEST|52=20241119-04:27:39.897364|369=12|123=Y|36=16|10=120|
2024/11/19 04:27:48.834779 8=FIXT.1.1|9=102|35=0|49=Coinbase|56=myuser|34=16|50=TEST|52=20241119-04:27:48.935898|369=12|10=113|
2024/11/19 04:27:49.740027 8=FIXT.1.1|9=84|35=0|34=13|49=myuser|52=20241119-04:27:49.725|56=Coinbase|10=118|
2024/11/19 04:27:57.835079 8=FIXT.1.1|9=102|35=0|49=Coinbase|56=myuser|34=17|50=TEST|52=20241119-04:27:57.936187|369=13|10=107|
2024/11/19 04:27:59.761167 8=FIXT.1.1|9=84|35=0|34=14|49=myuser|52=20241119-04:27:59.740|56=Coinbase|10=117|
2024/11/19 04:28:06.845546 8=FIXT.1.1|9=102|35=0|49=Coinbase|56=myuser|34=18|50=TEST|52=20241119-04:28:06.936317|369=14|10=099|
2024/11/19 04:28:09.780998 8=FIXT.1.1|9=84|35=0|34=15|49=myuser|52=20241119-04:28:09.762|56=Coinbase|10=118|
2024/11/19 04:28:15.836470 8=FIXT.1.1|9=102|35=0|49=Coinbase|56=myuser|34=19|50=TEST|52=20241119-04:28:15.936565|369=15|10=106|
2024/11/19 04:28:19.798929 8=FIXT.1.1|9=84|35=0|34=16|49=myuser|52=20241119-04:28:19.782|56=Coinbase|10=122|
2024/11/19 04:28:19.836487 8=FIXT.1.1|9=112|35=1|49=Coinbase|56=myuser|34=20|50=TEST|52=20241119-04:28:19.936558|369=15|112=12345|10=059|
2024/11/19 04:28:19.852480 8=FIXT.1.1|9=94|35=0|34=17|49=myuser|52=20241119-04:28:19.836|56=Coinbase|112=12345|10=077|