func (e *EchoApplication) processMsg(msg *quickfix.Message, sessionID quickfix.SessionID) quickfix.MessageRejectError { var possResend field.PossResendField msg.Header.Get(&possResend) if msg.Body.Has(tag.ClOrdID) { var orderID field.ClOrdIDField if err := msg.Body.Get(&orderID); err != nil { return err } sessionOrderID := sessionID.String() + orderID.String() if possResend.FIXBoolean { if e.OrderIds[sessionOrderID] { return nil } } e.OrderIds[sessionOrderID] = true } reply := copyMessage(msg) if possResend.FIXBoolean { reply.Header.Set(possResend) } quickfix.SendToTarget(reply, sessionID) return nil }
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 }
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 }
// Common Order FIX client routines serving requests from order router // if a market connector has special case it will need to implement its own start routine like below func (app FIXClient) Start() error { err := app.Initiator.Start() // Subscribe to order flow topics // NEW app.MessageBus.Subscribe("order.NewOrderRequest.MC."+app.marketConnectorName, func(m *messagebus.Msg) { request := new(proto.NewOrderRequest) if err := request.Unmarshal(m.Data); err == nil { order := request.Order //TODO: this is only prototype, migrate common tasks: instruments / limits processing fixmsg := fix44nos.Message{ ClOrdID: strconv.Itoa(int(order.OrderKey)) + "." + strconv.Itoa(int(order.Version)), Side: util.ProtoEnumToFIXEnum(int(order.Side)), TransactTime: time.Now(), OrdType: util.ProtoEnumToFIXEnum(int(order.OrderType)), } // Instrument specific fixmsg.Instrument.Symbol = &order.Symbol fixmsg.OrderQty = &order.Quantity if order.OrderType == proto.OrderType_LIMIT || order.OrderType == proto.OrderType_LIMIT_ON_CLOSE { fixmsg.Price = &order.LimitPrice } // Broker specific fixmsg.Account = &order.BrokerAccount fixmsg.HandlInst = stringPtr(util.ProtoEnumToFIXEnum(int(order.HandleInst))) // 142 SenderLocationID // Mandatory for CME exchanges. It contains a 2-character country. For the US and Canada, the state/province is included. fixmsg.SenderLocationID = stringPtr("UK") log.Info("MC->FIX FIX44NewOrderSingle") if err := quickfix.SendToTarget(fixmsg, app.Session); err != nil { log.WithError(err).Fatal("FIX quickfix.SendToTarget Error") } } }) // TODO: CANCEL // TODO: REPLACE return err }
func main() { flag.Parse() cfg, err := os.Open(*fixconfig) if err != nil { log.Fatal(err) } appSettings, err := quickfix.ParseSettings(cfg) if err != nil { log.Fatal(err) } // logFactory, err := quickfix.NewFileLogFactory(appSettings) logFactory := quickfix.NewNullLogFactory() if err != nil { log.Fatal(err) } storeFactory := quickfix.NewMemoryStoreFactory() initiator, err := quickfix.NewInitiator(app, storeFactory, appSettings, logFactory) if err != nil { log.Fatal(err) } if err = initiator.Start(); err != nil { log.Fatal(err) } <-start for i := 0; i < *sampleSize; i++ { order := newordersingle.Builder( field.NewClOrdID("100"), field.NewHandlInst("1"), field.NewSymbol("TSLA"), field.NewSide(enum.Side_BUY), &field.TransactTimeField{}, field.NewOrdType(enum.OrdType_MARKET)) quickfix.SendToTarget(order, SessionID) // time.Sleep(1 * time.Millisecond) } time.Sleep(2 * time.Second) }
func main() { flag.Parse() cfg, err := os.Open(*fixconfig) if err != nil { log.Fatal(err) } appSettings, err := quickfix.ParseSettings(cfg) if err != nil { log.Fatal(err) } // logFactory, err := quickfix.NewFileLogFactory(appSettings) logFactory := quickfix.NewNullLogFactory() if err != nil { log.Fatal(err) } storeFactory := quickfix.NewMemoryStoreFactory() initiator, err := quickfix.NewInitiator(app, storeFactory, appSettings, logFactory) if err != nil { log.Fatal(err) } if err = initiator.Start(); err != nil { log.Fatal(err) } <-start for i := 0; i < *sampleSize; i++ { order := newordersingle.Message{} order.ClOrdID = "100" order.HandlInst = "1" order.Symbol = "TSLA" order.Side = enum.Side_BUY order.TransactTime = time.Now() order.OrdType = enum.OrdType_MARKET quickfix.SendToTarget(order, SessionID) // time.Sleep(1 * time.Millisecond) } time.Sleep(2 * time.Second) }
//START OMIT func (i *InitiatorApp) OnLogon(sessionID quickfix.SessionID) { log.Print("OnLogon ", sessionID) go func() { for i := 0; i < 100; i++ { order := newordersingle.Message{ ClOrdID: strconv.Itoa(i), HandlInst: "1", Symbol: "TSLA", Side: enum.Side_BUY, TransactTime: time.Now(), OrdType: enum.OrdType_MARKET, } log.Print("Sending Order...") quickfix.SendToTarget(order, sessionID) time.Sleep(1 * time.Second) } i.complete <- sessionID }() }
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 *EchoApplication) OnFIX50SP2SecurityDefinition(msg fix50sp2secdef.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { reply := copyMessageToBuilder(msg.Message) quickfix.SendToTarget(reply, 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 }