Beispiel #1
0
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
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
}
Beispiel #7
0
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)
}
Beispiel #8
0
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)
}
Beispiel #9
0
//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
	}()
}
Beispiel #10
0
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
}
Beispiel #11
0
func (e *EchoApplication) OnFIX50SP2SecurityDefinition(msg fix50sp2secdef.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) {
	reply := copyMessageToBuilder(msg.Message)
	quickfix.SendToTarget(reply, sessionID)
	return
}
Beispiel #12
0
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
}