func (e *Executor) OnFIX50NewOrderSingle(msg fix50nos.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { symbol, err := msg.Symbol() if err != nil { return } side, err := msg.Side() if err != nil { return } orderQty, err := msg.OrderQty() if err != nil { return } ordType, err := msg.OrdType() if err != nil { return } if ordType.Value != enum.OrdType_LIMIT { err = quickfix.ValueIsIncorrect(ordType.Tag()) return } price, err := msg.Price() if err != nil { return } clOrdID, err := msg.ClOrdID() if err != nil { return } execReport := fix50er.Builder( field.NewOrderID(e.genOrderID()), field.NewExecID(e.genExecID()), field.NewExecType(enum.ExecType_FILL), field.NewOrdStatus(enum.OrdStatus_FILLED), side, field.NewLeavesQty(0), field.NewCumQty(orderQty.Value)) execReport.Body().Set(clOrdID) execReport.Body().Set(symbol) execReport.Body().Set(orderQty) execReport.Body().Set(field.NewLastQty(orderQty.Value)) execReport.Body().Set(field.NewLastPx(price.Value)) execReport.Body().Set(field.NewAvgPx(price.Value)) if acct, err := msg.Account(); err != nil { execReport.Body().Set(acct) } quickfix.SendToTarget(execReport.MessageBuilder, sessionID) return }
func (e *Executor) OnFIX44NewOrderSingle(msg fix44nos.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { if msg.OrdType != enum.OrdType_LIMIT { err = quickfix.ValueIsIncorrect(tag.OrdType) return } execReport := fix44er.Message{ ClOrdID: &msg.ClOrdID, Account: msg.Account, OrderID: e.genOrderID(), ExecID: e.genExecID(), ExecType: enum.ExecType_FILL, OrdStatus: enum.OrdStatus_FILLED, Side: msg.Side, Instrument: msg.Instrument, OrderQtyData: &msg.OrderQtyData, LeavesQty: 0, LastQty: msg.OrderQtyData.OrderQty, CumQty: *msg.OrderQtyData.OrderQty, AvgPx: *msg.Price, LastPx: msg.Price, LastMkt: stringPtr("SIM"), } quickfix.SendToTarget(execReport, sessionID) return }
// Common behaviours to persist and publish populated Execution entity into our data layer and message bus func (app FIXClient) processExecutionReport(er *proto.Execution) quickfix.MessageRejectError { // Find the Order by using the OrderKey without the Version // Need to try to LOAD the order, if that fails then alert stating unsolicited order received keyVersion := strings.Split(er.ClientOrderId, ".") if len(keyVersion) != 2 { return quickfix.ValueIsIncorrect(tag.ClOrdID) } if oKey, err := strconv.Atoi(keyVersion[0]); err != nil { return quickfix.ValueIsIncorrect(tag.ClOrdID) } else { if ord, err := app.OrderStore.OrderGetByOrderKey(int32(oKey)); err != nil { log.WithError(err).Warnf("Received ExecutionReport with OrderKey(%v) does not exist.", oKey) return nil // TODO: ignore or quickfix.ValueIsIncorrect(tag.ClOrdID) } else { er.OrderId = ord.OrderId } } // Persist the execution report if err := app.OrderStore.ExecutionCreate(er); err == nil { //publish to message bus data, _ := er.Marshal() app.MessageBus.Publish("order.Execution", data) } else { log.WithField("execution", er).WithError(err).Error("[ MC ] ERROR Create Reject Execution") } // Do any validating and if we are good to continue // Check if we need to cancel any execution // Check if we need to correct any execution switch er.ExecType { case proto.Execution_TRADE_CANCEL: case proto.Execution_TRADE_CORRECT: //TODO: TryGetAmendedExecution case proto.Execution_RESTATED: case proto.Execution_REJECTED: } // Check if the trade is fully filled or is done for day or canceled // .. Send message to TradePump to say trade filled and already to book. return nil }
func (e *executor) OnFIX41NewOrderSingle(msg fix41nos.NewOrderSingle, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { ordType, err := msg.GetOrdType() if err != nil { return } if ordType != enum.OrdType_LIMIT { return quickfix.ValueIsIncorrect(tag.OrdType) } symbol, err := msg.GetSymbol() if err != nil { return } side, err := msg.GetSide() if err != nil { return } orderQty, err := msg.GetOrderQty() if err != nil { return } price, err := msg.GetPrice() if err != nil { return } execReport := fix41er.New( e.genOrderID(), e.genExecID(), field.NewExecTransType(enum.ExecTransType_NEW), field.NewExecType(enum.ExecType_FILL), field.NewOrdStatus(enum.OrdStatus_FILLED), field.NewSymbol(symbol), field.NewSide(side), field.NewOrderQty(orderQty, 2), field.NewLastShares(orderQty, 2), field.NewLastPx(price, 2), field.NewLeavesQty(decimal.Zero, 2), field.NewCumQty(orderQty, 2), field.NewAvgPx(price, 2), ) clOrdID, err := msg.GetClOrdID() if err != nil { return } execReport.SetClOrdID(clOrdID) quickfix.SendToTarget(execReport, sessionID) return }
func (e *executor) OnFIX41NewOrderSingle(msg fix41nos.NewOrderSingle, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { var ordType field.OrdTypeField if ordType, err = msg.GetOrdType(); err != nil { return err } if ordType.String() != enum.OrdType_LIMIT { return quickfix.ValueIsIncorrect(tag.OrdType) } var symbol field.SymbolField if symbol, err = msg.GetSymbol(); err != nil { return } var side field.SideField if side, err = msg.GetSide(); err != nil { return } var orderQty field.OrderQtyField if orderQty, err = msg.GetOrderQty(); err != nil { return } var price field.PriceField if price, err = msg.GetPrice(); err != nil { return } execReport := fix41er.New( e.genOrderID(), e.genExecID(), field.NewExecTransType(enum.ExecTransType_NEW), field.NewExecType(enum.ExecType_FILL), field.NewOrdStatus(enum.OrdStatus_FILLED), symbol, side, orderQty, field.NewLastShares(orderQty.Float64()), field.NewLastPx(price.Float64()), field.NewLeavesQty(0), field.NewCumQty(orderQty.Float64()), field.NewAvgPx(price.Float64()), ) quickfix.SendToTarget(execReport, sessionID) return }
func (e *executor) OnFIX50NewOrderSingle(msg fix50nos.NewOrderSingle, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { ordType, err := msg.GetOrdType() if err != nil { return err } if ordType != enum.OrdType_LIMIT { return quickfix.ValueIsIncorrect(tag.OrdType) } symbol, err := msg.GetSymbol() if err != nil { return } side, err := msg.GetSide() if err != nil { return } orderQty, err := msg.GetOrderQty() if err != nil { return } price, err := msg.GetPrice() if err != nil { return } clOrdID, err := msg.GetClOrdID() if err != nil { return } execReport := fix50er.New( e.genOrderID(), e.genExecID(), field.NewExecType(enum.ExecType_FILL), field.NewOrdStatus(enum.OrdStatus_FILLED), field.NewSide(side), field.NewLeavesQty(decimal.Zero, 2), field.NewCumQty(orderQty, 2), ) execReport.SetClOrdID(clOrdID) execReport.SetSymbol(symbol) execReport.SetOrderQty(orderQty, 2) execReport.SetLastQty(orderQty, 2) execReport.SetLastPx(price, 2) execReport.SetAvgPx(price, 2) if msg.HasAccount() { acct, err := msg.GetAccount() if err != nil { return err } execReport.SetAccount(acct) } quickfix.SendToTarget(execReport, sessionID) return }
func (e *executor) OnFIX50NewOrderSingle(msg fix50nos.NewOrderSingle, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { var ordType field.OrdTypeField if ordType, err = msg.GetOrdType(); err != nil { return err } if ordType.String() != enum.OrdType_LIMIT { return quickfix.ValueIsIncorrect(tag.OrdType) } var symbol field.SymbolField if symbol, err = msg.GetSymbol(); err != nil { return } var side field.SideField if side, err = msg.GetSide(); err != nil { return } var orderQty field.OrderQtyField if orderQty, err = msg.GetOrderQty(); err != nil { return } var price field.PriceField if price, err = msg.GetPrice(); err != nil { return } var clOrdID field.ClOrdIDField if clOrdID, err = msg.GetClOrdID(); err != nil { return } execReport := fix50er.New( e.genOrderID(), e.genExecID(), field.NewExecType(enum.ExecType_FILL), field.NewOrdStatus(enum.OrdStatus_FILLED), side, field.NewLeavesQty(0), field.NewCumQty(orderQty.Float64()), ) execReport.Set(clOrdID) execReport.Set(symbol) execReport.Set(orderQty) execReport.SetLastQty(orderQty.Float64()) execReport.SetLastPx(price.Float64()) execReport.SetAvgPx(price.Float64()) if msg.HasAccount() { var acct field.AccountField if acct, err = msg.GetAccount(); err != nil { return err } execReport.Set(acct) } quickfix.SendToTarget(execReport, sessionID) return }