package fix import ( "log/slog" "quantex.com/qfixpt/quickfix" "quantex.com/qfixpt/quickfix/gen/fix50sp2/allocationreport" "quantex.com/qfixpt/quickfix/gen/fix50sp2/confirmation" "quantex.com/qfixpt/quickfix/gen/fix50sp2/tradecapturereport" "quantex.com/qfixpt/quickfix/gen/tag" "quantex.com/qfixpt/src/domain" ) type application struct { router *quickfix.MessageRouter notifier domain.Notifier onLogon func(quickfix.SessionID) onLogout func(quickfix.SessionID) onTradeCaptureReport func(tradecapturereport.TradeCaptureReport, quickfix.SessionID) onAllocationReport func(allocationreport.AllocationReport, quickfix.SessionID) onConfirmation func(confirmation.Confirmation, quickfix.SessionID) } func newApplication(n domain.Notifier) *application { app := &application{ router: quickfix.NewMessageRouter(), notifier: n, } app.router.AddRoute(tradecapturereport.Route(app.handleTradeCaptureReport)) app.router.AddRoute(allocationreport.Route(app.handleAllocationReport)) app.router.AddRoute(confirmation.Route(app.handleConfirmation)) return app } func (a *application) OnCreate(sessionID quickfix.SessionID) { slog.Info("FIX session created", "session", sessionID.String()) } func (a *application) OnLogon(sessionID quickfix.SessionID) { slog.Info("FIX session logged on", "session", sessionID.String()) if a.onLogon != nil { a.onLogon(sessionID) } } func (a *application) OnLogout(sessionID quickfix.SessionID) { slog.Info("FIX session logged out", "session", sessionID.String()) go a.notifier.SendMsg(domain.MessageChannelError, "Logout", domain.MessageStatusWarning, nil) if a.onLogout != nil { a.onLogout(sessionID) } } func (a *application) ToAdmin(_ *quickfix.Message, _ quickfix.SessionID) {} func (a *application) ToApp(_ *quickfix.Message, _ quickfix.SessionID) error { return nil } func (a *application) FromAdmin(_ *quickfix.Message, _ quickfix.SessionID) quickfix.MessageRejectError { return nil } func (a *application) FromApp(msg *quickfix.Message, sessionID quickfix.SessionID) quickfix.MessageRejectError { beginString, _ := msg.Header.GetBytes(tag.BeginString) msgType, _ := msg.Header.GetBytes(tag.MsgType) var applVerID quickfix.FIXString msg.Header.GetField(tag.ApplVerID, &applVerID) slog.Info("FIX FromApp received", "beginString", string(beginString), "msgType", string(msgType), "applVerID", string(applVerID), "session", sessionID.String(), "rawMsg", msg.String(), ) rejErr := a.router.Route(msg, sessionID) if rejErr != nil { slog.Error("FIX FromApp routing failed", "msgType", string(msgType), "error", rejErr.Error(), "isBusinessReject", rejErr.IsBusinessReject(), ) } return rejErr } func (a *application) handleTradeCaptureReport(msg tradecapturereport.TradeCaptureReport, sessionID quickfix.SessionID) quickfix.MessageRejectError { tradeReportID, _ := msg.GetTradeReportID() slog.Info("TradeCaptureReport received", "tradeReportID", tradeReportID, "session", sessionID.String(), ) if a.onTradeCaptureReport != nil { a.onTradeCaptureReport(msg, sessionID) } return nil } func (a *application) handleAllocationReport(msg allocationreport.AllocationReport, sessionID quickfix.SessionID) quickfix.MessageRejectError { allocReportID, _ := msg.GetAllocReportID() slog.Info("AllocationReport received", "allocReportID", allocReportID, "session", sessionID.String(), ) if a.onAllocationReport != nil { a.onAllocationReport(msg, sessionID) } return nil } func (a *application) handleConfirmation(msg confirmation.Confirmation, sessionID quickfix.SessionID) quickfix.MessageRejectError { confirmID, _ := msg.GetConfirmID() slog.Info("Confirmation received", "confirmID", confirmID, "session", sessionID.String(), ) if a.onConfirmation != nil { a.onConfirmation(msg, sessionID) } return nil }