From 130c09a63bc5d57c56e768085cb8d6a1118c2aa7 Mon Sep 17 00:00:00 2001 From: Chris Busbey Date: Thu, 11 Feb 2016 19:20:35 -0800 Subject: [PATCH] updated for latest master, uses glide for vendoring --- {executor => config}/executor.cfg | 0 {tradeclient => config}/tradeclient.cfg | 0 executor/executor.go | 425 ++++++---------- glide.lock | 22 + glide.yaml | 19 + tradeclient/console.go | 624 ++++++++++++------------ tradeclient/tradeclient.go | 13 +- 7 files changed, 499 insertions(+), 604 deletions(-) rename {executor => config}/executor.cfg (100%) rename {tradeclient => config}/tradeclient.cfg (100%) create mode 100644 glide.lock create mode 100644 glide.yaml diff --git a/executor/executor.cfg b/config/executor.cfg similarity index 100% rename from executor/executor.cfg rename to config/executor.cfg diff --git a/tradeclient/tradeclient.cfg b/config/tradeclient.cfg similarity index 100% rename from tradeclient/tradeclient.cfg rename to config/tradeclient.cfg diff --git a/executor/executor.go b/executor/executor.go index 8eebc93..c0a2c66 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -1,10 +1,11 @@ package main import ( + "flag" "fmt" "github.com/quickfixgo/quickfix" - "github.com/quickfixgo/quickfix/fix/enum" - "github.com/quickfixgo/quickfix/fix/field" + "github.com/quickfixgo/quickfix/enum" + "github.com/quickfixgo/quickfix/tag" fix40nos "github.com/quickfixgo/quickfix/fix40/newordersingle" fix41nos "github.com/quickfixgo/quickfix/fix41/newordersingle" @@ -48,17 +49,17 @@ func (e *Executor) genOrderID() string { return strconv.Itoa(e.orderID) } -func (e *Executor) genExecID() string { +func (e *Executor) genExecID() int { e.execID++ - return strconv.Itoa(e.execID) + return e.execID } //quickfix.Application interface -func (e Executor) OnCreate(sessionID quickfix.SessionID) { return } -func (e Executor) OnLogon(sessionID quickfix.SessionID) { return } -func (e Executor) OnLogout(sessionID quickfix.SessionID) { return } -func (e Executor) ToAdmin(msg quickfix.MessageBuilder, sessionID quickfix.SessionID) { return } -func (e Executor) ToApp(msg quickfix.MessageBuilder, sessionID quickfix.SessionID) error { return nil } +func (e Executor) OnCreate(sessionID quickfix.SessionID) { return } +func (e Executor) OnLogon(sessionID quickfix.SessionID) { return } +func (e Executor) OnLogout(sessionID quickfix.SessionID) { return } +func (e Executor) ToAdmin(msg quickfix.Message, sessionID quickfix.SessionID) { return } +func (e Executor) ToApp(msg quickfix.Message, sessionID quickfix.SessionID) error { return nil } func (e Executor) FromAdmin(msg quickfix.Message, sessionID quickfix.SessionID) quickfix.MessageRejectError { return nil } @@ -69,368 +70,236 @@ func (e *Executor) FromApp(msg quickfix.Message, sessionID quickfix.SessionID) ( } func (e *Executor) OnFIX40NewOrderSingle(msg fix40nos.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 { + if msg.OrdType != enum.OrdType_LIMIT { + err = quickfix.ValueIsIncorrect(tag.OrdType) return } - clOrdID, err := msg.ClOrdID() - if err != nil { + if msg.Price == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.Price) return } - execReport := fix40er.Builder( - field.NewOrderID(e.genOrderID()), - field.NewExecID(e.genExecID()), - field.NewExecTransType(enum.ExecTransType_NEW), - field.NewOrdStatus(enum.OrdStatus_FILLED), - symbol, side, orderQty, field.NewLastShares(orderQty.Value), field.NewLastPx(price.Value), field.NewCumQty(orderQty.Value), field.NewAvgPx(price.Value)) - - execReport.Body().Set(clOrdID) - - if acct, err := msg.Account(); err != nil { - execReport.Body().Set(acct) + execReport := fix40er.Message{ + ClOrdID: &msg.ClOrdID, + Account: msg.Account, + OrderID: e.genOrderID(), + ExecID: e.genExecID(), + ExecTransType: enum.ExecTransType_NEW, + OrdStatus: enum.OrdStatus_FILLED, + Symbol: msg.Symbol, + Side: msg.Side, + OrderQty: msg.OrderQty, + LastShares: msg.OrderQty, + LastPx: *msg.Price, + CumQty: msg.OrderQty, + AvgPx: *msg.Price, } - quickfix.SendToTarget(execReport.MessageBuilder, sessionID) + quickfix.SendToTarget(execReport, sessionID) return } func (e *Executor) OnFIX41NewOrderSingle(msg fix41nos.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { - symbol, err := msg.Symbol() - if err != nil { + if msg.OrdType != enum.OrdType_LIMIT { + err = quickfix.ValueIsIncorrect(tag.OrdType) return } - side, err := msg.Side() - if err != nil { + if msg.Price == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.Price) return } - orderQty, err := msg.OrderQty() - if err != nil { + if msg.OrderQty == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.OrderQty) return } - ordType, err := msg.OrdType() - if err != nil { - return + execReport := fix41er.Message{ + ClOrdID: &msg.ClOrdID, + Account: msg.Account, + OrderID: e.genOrderID(), + ExecID: strconv.Itoa(e.genExecID()), + ExecTransType: enum.ExecTransType_NEW, + ExecType: enum.ExecType_FILL, + OrdStatus: enum.OrdStatus_FILLED, + Symbol: msg.Symbol, + Side: msg.Side, + OrderQty: *msg.OrderQty, + LastShares: *msg.OrderQty, + LastPx: *msg.Price, + LeavesQty: 0, + CumQty: *msg.OrderQty, + AvgPx: *msg.Price, } - 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 := fix41er.Builder( - field.NewOrderID(e.genOrderID()), - field.NewExecID(e.genExecID()), - field.NewExecTransType(enum.ExecTransType_NEW), - field.NewExecType(enum.ExecType_FILL), - field.NewOrdStatus(enum.OrdStatus_FILLED), - symbol, - side, - orderQty, - field.NewLastShares(orderQty.Value), - field.NewLastPx(price.Value), - field.NewLeavesQty(0), - field.NewCumQty(orderQty.Value), - field.NewAvgPx(price.Value)) - - execReport.Body().Set(clOrdID) - - if acct, err := msg.Account(); err != nil { - execReport.Body().Set(acct) - } - - quickfix.SendToTarget(execReport.MessageBuilder, sessionID) + quickfix.SendToTarget(execReport, sessionID) return } func (e *Executor) OnFIX42NewOrderSingle(msg fix42nos.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { - symbol, err := msg.Symbol() - if err != nil { + if msg.OrdType != enum.OrdType_LIMIT { + err = quickfix.ValueIsIncorrect(tag.OrdType) return } - side, err := msg.Side() - if err != nil { + if msg.Price == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.Price) 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 { + if msg.OrderQty == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.OrderQty) return } - execReport := fix42er.Builder( - field.NewOrderID(e.genOrderID()), - field.NewExecID(e.genExecID()), - field.NewExecTransType(enum.ExecTransType_NEW), - field.NewExecType(enum.ExecType_FILL), - field.NewOrdStatus(enum.OrdStatus_FILLED), - symbol, - side, - field.NewLeavesQty(0), - field.NewCumQty(orderQty.Value), - field.NewAvgPx(price.Value)) - - execReport.Body().Set(clOrdID) - execReport.Body().Set(orderQty) - execReport.Body().Set(field.NewLastShares(orderQty.Value)) - execReport.Body().Set(field.NewLastPx(price.Value)) - - if acct, err := msg.Account(); err != nil { - execReport.Body().Set(acct) + execReport := fix42er.Message{ + ClOrdID: &msg.ClOrdID, + Account: msg.Account, + OrderID: e.genOrderID(), + ExecID: strconv.Itoa(e.genExecID()), + ExecTransType: enum.ExecTransType_NEW, + ExecType: enum.ExecType_FILL, + OrdStatus: enum.OrdStatus_FILLED, + Symbol: msg.Symbol, + Side: msg.Side, + OrderQty: msg.OrderQty, + LeavesQty: 0, + LastShares: msg.OrderQty, + CumQty: *msg.OrderQty, + AvgPx: *msg.Price, + LastPx: msg.Price, } - quickfix.SendToTarget(execReport.MessageBuilder, sessionID) + quickfix.SendToTarget(execReport, sessionID) return } func (e *Executor) OnFIX43NewOrderSingle(msg fix43nos.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { - symbol, err := msg.Symbol() - if err != nil { - return - } - - side, err := msg.Side() - if err != nil { + if msg.OrdType != enum.OrdType_LIMIT { + err = quickfix.ValueIsIncorrect(tag.OrdType) return } - orderQty, err := msg.OrderQty() - if err != nil { + if msg.Price == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.Price) return } - ordType, err := msg.OrdType() - if err != nil { + if msg.OrderQtyData.OrderQty == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.OrderQty) return } - if ordType.Value != enum.OrdType_LIMIT { - err = quickfix.ValueIsIncorrect(ordType.Tag()) - return + execReport := fix43er.Message{ + ClOrdID: &msg.ClOrdID, + Account: msg.Account, + OrderID: e.genOrderID(), + ExecID: strconv.Itoa(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, } - - price, err := msg.Price() - if err != nil { - return - } - - clOrdID, err := msg.ClOrdID() - if err != nil { - return - } - - execReport := fix43er.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), - field.NewAvgPx(price.Value)) - - execReport.Body().Set(clOrdID) - execReport.Body().Set(symbol) - execReport.Body().Set(orderQty) - execReport.Body().Set(field.NewLastShares(orderQty.Value)) - execReport.Body().Set(field.NewLastPx(price.Value)) - - if acct, err := msg.Account(); err != nil { - execReport.Body().Set(acct) - } - - quickfix.SendToTarget(execReport.MessageBuilder, sessionID) + quickfix.SendToTarget(execReport, sessionID) return } func (e *Executor) OnFIX44NewOrderSingle(msg fix44nos.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()) + if msg.OrdType != enum.OrdType_LIMIT { + err = quickfix.ValueIsIncorrect(tag.OrdType) return } - price, err := msg.Price() - if err != nil { + if msg.Price == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.Price) return } - clOrdID, err := msg.ClOrdID() - if err != nil { + if msg.OrderQtyData.OrderQty == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.OrderQty) return } - execReport := fix44er.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), - field.NewAvgPx(price.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)) - - if acct, err := msg.Account(); err != nil { - execReport.Body().Set(acct) + execReport := fix44er.Message{ + ClOrdID: &msg.ClOrdID, + OrderID: e.genOrderID(), + Account: msg.Account, + ExecID: strconv.Itoa(e.genExecID()), + ExecType: enum.ExecType_FILL, + OrdStatus: enum.OrdStatus_FILLED, + Side: msg.Side, + Instrument: msg.Instrument, + LeavesQty: 0, + CumQty: *msg.OrderQtyData.OrderQty, + LastQty: msg.OrderQtyData.OrderQty, + OrderQtyData: msg.OrderQtyData, + AvgPx: *msg.Price, + LastPx: msg.Price, } - quickfix.SendToTarget(execReport.MessageBuilder, sessionID) + quickfix.SendToTarget(execReport, sessionID) return } func (e *Executor) OnFIX50NewOrderSingle(msg fix50nos.Message, sessionID quickfix.SessionID) (err quickfix.MessageRejectError) { - symbol, err := msg.Symbol() - if err != nil { + if msg.OrdType != enum.OrdType_LIMIT { + err = quickfix.ValueIsIncorrect(tag.OrdType) return } - side, err := msg.Side() - if err != nil { + if msg.Price == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.Price) return } - orderQty, err := msg.OrderQty() - if err != nil { + if msg.OrderQtyData.OrderQty == nil { + err = quickfix.ConditionallyRequiredFieldMissing(tag.OrderQty) return } - ordType, err := msg.OrdType() - if err != nil { - return + execReport := fix50er.Message{ + ClOrdID: &msg.ClOrdID, + Instrument: msg.Instrument, + Account: msg.Account, + OrderID: e.genOrderID(), + ExecID: strconv.Itoa(e.genExecID()), + ExecType: enum.ExecType_FILL, + OrdStatus: enum.OrdStatus_FILLED, + Side: msg.Side, + OrderQtyData: msg.OrderQtyData, + LastQty: msg.OrderQtyData.OrderQty, + LeavesQty: 0, + CumQty: *msg.OrderQtyData.OrderQty, + LastPx: msg.Price, + AvgPx: msg.Price, } - 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) + quickfix.SendToTarget(execReport, sessionID) return } func main() { + flag.Parse() + cfgFileName := "executor.cfg" + if flag.NArg() > 0 { + cfgFileName = flag.Arg(0) + } + cfg, err := os.Open(cfgFileName) if err != nil { fmt.Printf("Error opening %v, %v\n", cfgFileName, err) diff --git a/glide.lock b/glide.lock new file mode 100644 index 0000000..7315851 --- /dev/null +++ b/glide.lock @@ -0,0 +1,22 @@ +hash: 0367d5bfe960f3a05cb61de85f7ed8d8937cbf51c45460035ff9811b43e4d2fc +updated: 2016-02-11T17:22:27.865222536-08:00 +imports: +- name: github.com/quickfixgo/quickfix + version: 8afaa4bedc8557ecc22119ee92ab0a592a140528 + subpackages: + - enum + - field + - fix40/executionreport + - fix40/newordersingle + - fix41/executionreport + - fix41/newordersingle + - fix42/executionreport + - fix42/newordersingle + - fix43/executionreport + - fix43/newordersingle + - fix44/executionreport + - fix44/newordersingle + - fix50/executionreport + - fix50/newordersingle + - tag +devImports: [] diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 0000000..6380b26 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,19 @@ +package: github.com/quickfixgo/examples +import: +- package: github.com/quickfixgo/quickfix + subpackages: + - enum + - field + - fix40/executionreport + - fix40/newordersingle + - fix41/executionreport + - fix41/newordersingle + - fix42/executionreport + - fix42/newordersingle + - fix43/executionreport + - fix43/newordersingle + - fix44/executionreport + - fix44/newordersingle + - fix50/executionreport + - fix50/newordersingle + - tag diff --git a/tradeclient/console.go b/tradeclient/console.go index 4c6b04d..ff7580e 100644 --- a/tradeclient/console.go +++ b/tradeclient/console.go @@ -4,9 +4,8 @@ import ( "bufio" "fmt" "github.com/quickfixgo/quickfix" - "github.com/quickfixgo/quickfix/fix" - "github.com/quickfixgo/quickfix/fix/enum" - "github.com/quickfixgo/quickfix/fix/field" + "github.com/quickfixgo/quickfix/enum" + "github.com/quickfixgo/quickfix/field" fix40nos "github.com/quickfixgo/quickfix/fix40/newordersingle" fix41nos "github.com/quickfixgo/quickfix/fix41/newordersingle" @@ -18,6 +17,7 @@ import ( "os" "strconv" "strings" + "time" ) func queryAction() (string, error) { @@ -29,7 +29,7 @@ func queryAction() (string, error) { return scanner.Text(), scanner.Err() } -func queryVersion() (*field.BeginStringField, error) { +func queryVersion() (string, error) { fmt.Println() fmt.Println("1) FIX.4.0") fmt.Println("2) FIX.4.1") @@ -41,47 +41,47 @@ func queryVersion() (*field.BeginStringField, error) { scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return "", scanner.Err() } switch scanner.Text() { case "1": - return field.NewBeginString(fix.BeginString_FIX40), nil + return enum.BeginStringFIX40, nil case "2": - return field.NewBeginString(fix.BeginString_FIX41), nil + return enum.BeginStringFIX41, nil case "3": - return field.NewBeginString(fix.BeginString_FIX42), nil + return enum.BeginStringFIX42, nil case "4": - return field.NewBeginString(fix.BeginString_FIX43), nil + return enum.BeginStringFIX43, nil case "5": - return field.NewBeginString(fix.BeginString_FIX44), nil + return enum.BeginStringFIX44, nil case "6": - return field.NewBeginString(fix.BeginString_FIXT11), nil + return enum.BeginStringFIXT11, nil case "7": - return field.NewBeginString("A"), nil + return "A", nil } - return nil, fmt.Errorf("unknown BeginString choice: %v", scanner.Text()) + return "", fmt.Errorf("unknown BeginString choice: %v", scanner.Text()) } -func queryClOrdID() (*field.ClOrdIDField, error) { +func queryClOrdID() (string, error) { fmt.Print("ClOrdID: ") scanner := bufio.NewScanner(os.Stdin) scanner.Scan() - return field.NewClOrdID(scanner.Text()), scanner.Err() + return scanner.Text(), scanner.Err() } -func querySymbol() (*field.SymbolField, error) { +func querySymbol() (string, error) { fmt.Println() fmt.Print("Symbol: ") scanner := bufio.NewScanner(os.Stdin) scanner.Scan() - return field.NewSymbol(scanner.Text()), scanner.Err() + return scanner.Text(), scanner.Err() } -func querySide() (*field.SideField, error) { +func querySide() (string, error) { fmt.Println() fmt.Println("1) Buy") @@ -95,30 +95,30 @@ func querySide() (*field.SideField, error) { scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return "", scanner.Err() } switch scanner.Text() { case "1": - return field.NewSide(enum.Side_BUY), nil + return enum.Side_BUY, nil case "2": - return field.NewSide(enum.Side_SELL), nil + return enum.Side_SELL, nil case "3": - return field.NewSide(enum.Side_SELL_SHORT), nil + return enum.Side_SELL_SHORT, nil case "4": - return field.NewSide(enum.Side_SELL_SHORT_EXEMPT), nil + return enum.Side_SELL_SHORT_EXEMPT, nil case "5": - return field.NewSide(enum.Side_CROSS), nil + return enum.Side_CROSS, nil case "6": - return field.NewSide(enum.Side_CROSS_SHORT), nil + return enum.Side_CROSS_SHORT, nil case "7": - return field.NewSide("A"), nil + return "A", nil } - return nil, fmt.Errorf("unknown side choice: %v", scanner.Text()) + return "", fmt.Errorf("unknown side choice: %v", scanner.Text()) } -func queryOrdType() (*field.OrdTypeField, error) { +func queryOrdType() (string, error) { fmt.Println() fmt.Println("1) Market") fmt.Println("2) Limit") @@ -128,24 +128,24 @@ func queryOrdType() (*field.OrdTypeField, error) { scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return "", scanner.Err() } switch scanner.Text() { case "1": - return field.NewOrdType(enum.OrdType_MARKET), nil + return enum.OrdType_MARKET, nil case "2": - return field.NewOrdType(enum.OrdType_LIMIT), nil + return enum.OrdType_LIMIT, nil case "3": - return field.NewOrdType(enum.OrdType_STOP), nil + return enum.OrdType_STOP, nil case "4": - return field.NewOrdType(enum.OrdType_STOP_LIMIT), nil + return enum.OrdType_STOP_LIMIT, nil } - return nil, fmt.Errorf("invalid ordtype choice: %v", scanner.Text()) + return "", fmt.Errorf("invalid ordtype choice: %v", scanner.Text()) } -func queryTimeInForce() (*field.TimeInForceField, error) { +func queryTimeInForce() (string, error) { fmt.Println() fmt.Println("1) Day") fmt.Println("2) IOC") @@ -156,72 +156,72 @@ func queryTimeInForce() (*field.TimeInForceField, error) { scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return "", scanner.Err() } switch scanner.Text() { case "1": - return field.NewTimeInForce(enum.TimeInForce_DAY), nil + return enum.TimeInForce_DAY, nil case "2": - return field.NewTimeInForce(enum.TimeInForce_IMMEDIATE_OR_CANCEL), nil + return enum.TimeInForce_IMMEDIATE_OR_CANCEL, nil case "3": - return field.NewTimeInForce(enum.TimeInForce_AT_THE_OPENING), nil + return enum.TimeInForce_AT_THE_OPENING, nil case "4": - return field.NewTimeInForce(enum.TimeInForce_GOOD_TILL_CANCEL), nil + return enum.TimeInForce_GOOD_TILL_CANCEL, nil case "5": - return field.NewTimeInForce(enum.TimeInForce_GOOD_TILL_CROSSING), nil + return enum.TimeInForce_GOOD_TILL_CROSSING, nil } - return nil, fmt.Errorf("invalid choice: %v", scanner.Text()) + return "", fmt.Errorf("invalid choice: %v", scanner.Text()) } -func queryOrderQty() (*field.OrderQtyField, error) { +func queryOrderQty() (float64, error) { fmt.Println() fmt.Print("OrderQty: ") scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return 0, scanner.Err() } val, err := strconv.ParseFloat(scanner.Text(), 64) if err != nil { - return nil, err + return 0, err } - return field.NewOrderQty(val), err + return val, err } -func queryPrice() (*field.PriceField, error) { +func queryPrice() (float64, error) { fmt.Println() fmt.Print("Price: ") scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return 0, scanner.Err() } val, err := strconv.ParseFloat(scanner.Text(), 64) if err != nil { - return nil, err + return 0, err } - return field.NewPrice(val), nil + return val, nil } -func queryStopPx() (*field.StopPxField, error) { +func queryStopPx() (float64, error) { fmt.Println() fmt.Print("Stop Price: ") scanner := bufio.NewScanner(os.Stdin) if !scanner.Scan() { - return nil, scanner.Err() + return 0, scanner.Err() } val, err := strconv.ParseFloat(scanner.Text(), 64) if err != nil { - return nil, err + return 0, err } - return field.NewStopPx(val), nil + return val, nil } func querySenderCompID() (*field.SenderCompIDField, error) { @@ -264,7 +264,7 @@ func queryConfirm(prompt string) bool { return strings.ToUpper(scanner.Text()) == "Y" } -func queryHeader(header quickfix.MutableFieldMap) error { +func queryHeader(header quickfix.FieldMap) error { senderCompID, err := querySenderCompID() if err != nil { return err @@ -290,363 +290,358 @@ func queryHeader(header quickfix.MutableFieldMap) error { return nil } -func queryNewOrderSingle40() (fix40nos.MessageBuilder, error) { - var builder fix40nos.MessageBuilder - - clOrdID, err := queryClOrdID() - if err != nil { - return builder, err +func queryNewOrderSingle40() (msg quickfix.Message, err error) { + order := fix40nos.Message{ + HandlInst: "1", } - symbol, err := querySymbol() - if err != nil { - return builder, err + if order.ClOrdID, err = queryClOrdID(); err != nil { + return } - side, err := querySide() - if err != nil { - return builder, err + if order.Symbol, err = querySymbol(); err != nil { + return } - orderQty, err := queryOrderQty() - if err != nil { - return builder, err + if order.Side, err = querySide(); err != nil { + return } - ordType, err := queryOrdType() - if err != nil { - return builder, err + if fVal, err := queryOrderQty(); err != nil { + return msg, err + } else { + order.OrderQty = int(fVal) } - builder = fix40nos.Builder(clOrdID, field.NewHandlInst("1"), symbol, side, orderQty, ordType) + if order.OrdType, err = queryOrdType(); err != nil { + return + } - timeInForce, err := queryTimeInForce() - if err != nil { - return builder, err + if tif, err := queryTimeInForce(); err != nil { + return msg, err + } else { + order.TimeInForce = &tif } - builder.Body().Set(timeInForce) - if ordType.Value == enum.OrdType_LIMIT || ordType.Value == enum.OrdType_STOP_LIMIT { - price, err := queryPrice() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_LIMIT, enum.OrdType_STOP_LIMIT: + if fVal, err := queryPrice(); err != nil { + return msg, err + } else { + order.Price = &fVal } - builder.Body().Set(price) } - if ordType.Value == enum.OrdType_STOP || ordType.Value == enum.OrdType_STOP_LIMIT { - stopPx, err := queryStopPx() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_STOP, enum.OrdType_STOP_LIMIT: + if fVal, err := queryStopPx(); err != nil { + return msg, err + } else { + order.StopPx = &fVal } - builder.Body().Set(stopPx) } - queryHeader(builder.Header()) + msg = quickfix.Marshal(order) + queryHeader(msg.Header) - return builder, nil + return } -func queryNewOrderSingle41() (fix41nos.MessageBuilder, error) { - var builder fix41nos.MessageBuilder +func queryNewOrderSingle41() (msg quickfix.Message, err error) { + order := fix41nos.Message{ + HandlInst: "1", + } - clOrdID, err := queryClOrdID() - if err != nil { - return builder, err + if order.ClOrdID, err = queryClOrdID(); err != nil { + return } - symbol, err := querySymbol() - if err != nil { - return builder, err + if order.Symbol, err = querySymbol(); err != nil { + return } - side, err := querySide() - if err != nil { - return builder, err + if order.Side, err = querySide(); err != nil { + return } - ordType, err := queryOrdType() - if err != nil { - return builder, err + if order.OrdType, err = queryOrdType(); err != nil { + return } - builder = fix41nos.Builder(clOrdID, field.NewHandlInst("1"), symbol, side, ordType) - orderQty, err := queryOrderQty() - if err != nil { - return builder, err + if fVal, err := queryOrderQty(); err != nil { + return msg, err + } else { + iVal := int(fVal) + order.OrderQty = &iVal } - builder.Body().Set(orderQty) - timeInForce, err := queryTimeInForce() - if err != nil { - return builder, err + if tif, err := queryTimeInForce(); err != nil { + return msg, err + } else { + order.TimeInForce = &tif } - builder.Body().Set(timeInForce) - if ordType.Value == enum.OrdType_LIMIT || ordType.Value == enum.OrdType_STOP_LIMIT { - price, err := queryPrice() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_LIMIT, enum.OrdType_STOP_LIMIT: + if fVal, err := queryPrice(); err != nil { + return msg, err + } else { + order.Price = &fVal } - builder.Body().Set(price) } - if ordType.Value == enum.OrdType_STOP || ordType.Value == enum.OrdType_STOP_LIMIT { - stopPx, err := queryStopPx() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_STOP, enum.OrdType_STOP_LIMIT: + if fVal, err := queryStopPx(); err != nil { + return msg, err + } else { + order.StopPx = &fVal } - builder.Body().Set(stopPx) + } - queryHeader(builder.Header()) + msg = quickfix.Marshal(order) + queryHeader(msg.Header) - return builder, nil + return } -func queryNewOrderSingle42() (fix42nos.MessageBuilder, error) { - var builder fix42nos.MessageBuilder - - clOrdID, err := queryClOrdID() - if err != nil { - return builder, err +func queryNewOrderSingle42() (msg quickfix.Message, err error) { + order := fix42nos.Message{ + HandlInst: "1", + TransactTime: time.Now(), } - symbol, err := querySymbol() - if err != nil { - return builder, err + if order.ClOrdID, err = queryClOrdID(); err != nil { + return } - side, err := querySide() - if err != nil { - return builder, err + if order.Symbol, err = querySymbol(); err != nil { + return } - ordType, err := queryOrdType() - if err != nil { - return builder, err + if order.Side, err = querySide(); err != nil { + return } - transactTime := &field.TransactTimeField{} - - builder = fix42nos.Builder(clOrdID, field.NewHandlInst("1"), symbol, side, transactTime, ordType) + if order.OrdType, err = queryOrdType(); err != nil { + return + } - orderQty, err := queryOrderQty() - if err != nil { - return builder, err + if fVal, err := queryOrderQty(); err != nil { + return msg, err + } else { + order.OrderQty = &fVal } - builder.Body().Set(orderQty) - timeInForce, err := queryTimeInForce() - if err != nil { - return builder, err + if tif, err := queryTimeInForce(); err != nil { + return msg, err + } else { + order.TimeInForce = &tif } - builder.Body().Set(timeInForce) - if ordType.Value == enum.OrdType_LIMIT || ordType.Value == enum.OrdType_STOP_LIMIT { - price, err := queryPrice() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_LIMIT, enum.OrdType_STOP_LIMIT: + if fVal, err := queryPrice(); err != nil { + return msg, err + } else { + order.Price = &fVal } - builder.Body().Set(price) } - if ordType.Value == enum.OrdType_STOP || ordType.Value == enum.OrdType_STOP_LIMIT { - stopPx, err := queryStopPx() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_STOP, enum.OrdType_STOP_LIMIT: + if fVal, err := queryStopPx(); err != nil { + return msg, err + } else { + order.StopPx = &fVal } - builder.Body().Set(stopPx) } - queryHeader(builder.Header()) - - return builder, nil + msg = quickfix.Marshal(order) + queryHeader(msg.Header) + return } -func queryNewOrderSingle43() (fix43nos.MessageBuilder, error) { - var builder fix43nos.MessageBuilder - - clOrdID, err := queryClOrdID() - if err != nil { - return builder, err +func queryNewOrderSingle43() (msg quickfix.Message, err error) { + order := fix43nos.Message{ + HandlInst: "1", + TransactTime: time.Now(), } - - side, err := querySide() - if err != nil { - return builder, err + if order.ClOrdID, err = queryClOrdID(); err != nil { + return } - ordType, err := queryOrdType() - if err != nil { - return builder, err + if sym, err := querySymbol(); err != nil { + return msg, err + } else { + order.Instrument.Symbol = &sym } - transactTime := &field.TransactTimeField{} - - builder = fix43nos.Builder(clOrdID, field.NewHandlInst("1"), side, transactTime, ordType) + if order.Side, err = querySide(); err != nil { + return + } - symbol, err := querySymbol() - if err != nil { - return builder, err + if order.OrdType, err = queryOrdType(); err != nil { + return } - builder.Body().Set(symbol) - orderQty, err := queryOrderQty() - if err != nil { - return builder, err + if fVal, err := queryOrderQty(); err != nil { + return msg, err + } else { + order.OrderQtyData.OrderQty = &fVal } - builder.Body().Set(orderQty) - timeInForce, err := queryTimeInForce() - if err != nil { - return builder, err + if tif, err := queryTimeInForce(); err != nil { + return msg, err + } else { + order.TimeInForce = &tif } - builder.Body().Set(timeInForce) - if ordType.Value == enum.OrdType_LIMIT || ordType.Value == enum.OrdType_STOP_LIMIT { - price, err := queryPrice() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_LIMIT, enum.OrdType_STOP_LIMIT: + if fVal, err := queryPrice(); err != nil { + return msg, err + } else { + order.Price = &fVal } - builder.Body().Set(price) } - if ordType.Value == enum.OrdType_STOP || ordType.Value == enum.OrdType_STOP_LIMIT { - stopPx, err := queryStopPx() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_STOP, enum.OrdType_STOP_LIMIT: + if fVal, err := queryStopPx(); err != nil { + return msg, err + } else { + order.StopPx = &fVal } - builder.Body().Set(stopPx) } - queryHeader(builder.Header()) + msg = quickfix.Marshal(order) + queryHeader(msg.Header) - return builder, nil + return } -func queryNewOrderSingle44() (fix44nos.MessageBuilder, error) { - var builder fix44nos.MessageBuilder - - clOrdID, err := queryClOrdID() - if err != nil { - return builder, err +func queryNewOrderSingle44() (msg quickfix.Message, err error) { + handleInst := "1" + order := fix44nos.Message{ + HandlInst: &handleInst, + TransactTime: time.Now(), } - side, err := querySide() - if err != nil { - return builder, err + if order.ClOrdID, err = queryClOrdID(); err != nil { + return } - ordType, err := queryOrdType() - if err != nil { - return builder, err + if sym, err := querySymbol(); err != nil { + return msg, err + } else { + order.Instrument.Symbol = &sym } - transactTime := &field.TransactTimeField{} - - builder = fix44nos.Builder(clOrdID, side, transactTime, ordType) + if order.Side, err = querySide(); err != nil { + return + } - builder.Body().Set(field.NewHandlInst("1")) - symbol, err := querySymbol() - if err != nil { - return builder, err + if order.OrdType, err = queryOrdType(); err != nil { + return } - builder.Body().Set(symbol) - orderQty, err := queryOrderQty() - if err != nil { - return builder, err + if fVal, err := queryOrderQty(); err != nil { + return msg, err + } else { + order.OrderQtyData.OrderQty = &fVal } - builder.Body().Set(orderQty) - timeInForce, err := queryTimeInForce() - if err != nil { - return builder, err + if tif, err := queryTimeInForce(); err != nil { + return msg, err + } else { + order.TimeInForce = &tif } - builder.Body().Set(timeInForce) - if ordType.Value == enum.OrdType_LIMIT || ordType.Value == enum.OrdType_STOP_LIMIT { - price, err := queryPrice() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_LIMIT, enum.OrdType_STOP_LIMIT: + if fVal, err := queryPrice(); err != nil { + return msg, err + } else { + order.Price = &fVal } - builder.Body().Set(price) } - if ordType.Value == enum.OrdType_STOP || ordType.Value == enum.OrdType_STOP_LIMIT { - stopPx, err := queryStopPx() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_STOP, enum.OrdType_STOP_LIMIT: + if fVal, err := queryStopPx(); err != nil { + return msg, err + } else { + order.StopPx = &fVal } - builder.Body().Set(stopPx) } - queryHeader(builder.Header()) + msg = quickfix.Marshal(order) + queryHeader(msg.Header) - return builder, nil + return } -func queryNewOrderSingle50() (fix50nos.MessageBuilder, error) { - var builder fix50nos.MessageBuilder - - clOrdID, err := queryClOrdID() - if err != nil { - return builder, err +func queryNewOrderSingle50() (msg quickfix.Message, err error) { + handleInst := "1" + order := fix50nos.Message{ + HandlInst: &handleInst, + TransactTime: time.Now(), } - side, err := querySide() - if err != nil { - return builder, err + if order.ClOrdID, err = queryClOrdID(); err != nil { + return } - ordType, err := queryOrdType() - if err != nil { - return builder, err + if sym, err := querySymbol(); err != nil { + return msg, err + } else { + order.Instrument.Symbol = &sym } - transactTime := &field.TransactTimeField{} - - builder = fix50nos.Builder(clOrdID, side, transactTime, ordType) + if order.Side, err = querySide(); err != nil { + return + } - builder.Body().Set(field.NewHandlInst("1")) - symbol, err := querySymbol() - if err != nil { - return builder, err + if order.OrdType, err = queryOrdType(); err != nil { + return } - builder.Body().Set(symbol) - orderQty, err := queryOrderQty() - if err != nil { - return builder, err + if fVal, err := queryOrderQty(); err != nil { + return msg, err + } else { + order.OrderQtyData.OrderQty = &fVal } - builder.Body().Set(orderQty) - timeInForce, err := queryTimeInForce() - if err != nil { - return builder, err + if tif, err := queryTimeInForce(); err != nil { + return msg, err + } else { + order.TimeInForce = &tif } - builder.Body().Set(timeInForce) - if ordType.Value == enum.OrdType_LIMIT || ordType.Value == enum.OrdType_STOP_LIMIT { - price, err := queryPrice() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_LIMIT, enum.OrdType_STOP_LIMIT: + if fVal, err := queryPrice(); err != nil { + return msg, err + } else { + order.Price = &fVal } - builder.Body().Set(price) } - if ordType.Value == enum.OrdType_STOP || ordType.Value == enum.OrdType_STOP_LIMIT { - stopPx, err := queryStopPx() - if err != nil { - return builder, err + switch order.OrdType { + case enum.OrdType_STOP, enum.OrdType_STOP_LIMIT: + if fVal, err := queryStopPx(); err != nil { + return msg, err + } else { + order.StopPx = &fVal } - builder.Body().Set(stopPx) } - queryHeader(builder.Header()) + msg = quickfix.Marshal(order) + queryHeader(msg.Header) - return builder, nil + return } func queryEnterOrder() error { @@ -655,50 +650,33 @@ func queryEnterOrder() error { return err } - var order *quickfix.MessageBuilder - switch beginString.Value { - case fix.BeginString_FIX40: - fix40Order, err := queryNewOrderSingle40() - if err != nil { - return err - } - order = &(fix40Order.MessageBuilder) + var order quickfix.Message + switch beginString { + case enum.BeginStringFIX40: + order, err = queryNewOrderSingle40() - case fix.BeginString_FIX41: - fix41Order, err := queryNewOrderSingle41() - if err != nil { - return err - } - order = &(fix41Order.MessageBuilder) + case enum.BeginStringFIX41: + order, err = queryNewOrderSingle41() - case fix.BeginString_FIX42: - fix42Order, err := queryNewOrderSingle42() - if err != nil { - return err - } - order = &(fix42Order.MessageBuilder) + case enum.BeginStringFIX42: + order, err = queryNewOrderSingle42() - case fix.BeginString_FIX43: - fix43Order, err := queryNewOrderSingle43() - if err != nil { - return err - } - order = &(fix43Order.MessageBuilder) + case enum.BeginStringFIX43: + order, err = queryNewOrderSingle43() - case fix.BeginString_FIX44: - fix44Order, err := queryNewOrderSingle44() - if err != nil { - return err - } - order = &(fix44Order.MessageBuilder) + case enum.BeginStringFIX44: + order, err = queryNewOrderSingle44() - case fix.BeginString_FIXT11: - fix50Order, err := queryNewOrderSingle50() - if err != nil { - return err - } - order = &(fix50Order.MessageBuilder) + case enum.BeginStringFIXT11: + order, err = queryNewOrderSingle50() + } + + if err != nil { + return err } + bytes, _ := order.Build() + + fmt.Println("Sending ", string(bytes)) - return quickfix.Send(*order) + return quickfix.Send(order) } diff --git a/tradeclient/tradeclient.go b/tradeclient/tradeclient.go index 9ea82be..74a0813 100644 --- a/tradeclient/tradeclient.go +++ b/tradeclient/tradeclient.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "github.com/quickfixgo/quickfix" "os" @@ -25,21 +26,27 @@ func (e TradeClient) FromAdmin(msg quickfix.Message, sessionID quickfix.SessionI return } -func (e TradeClient) ToAdmin(msg quickfix.MessageBuilder, sessionID quickfix.SessionID) { +func (e TradeClient) ToAdmin(msg quickfix.Message, sessionID quickfix.SessionID) { return } -func (e TradeClient) ToApp(msg quickfix.MessageBuilder, sessionID quickfix.SessionID) (err error) { +func (e TradeClient) ToApp(msg quickfix.Message, sessionID quickfix.SessionID) (err error) { return } func (e TradeClient) FromApp(msg quickfix.Message, sessionID quickfix.SessionID) (reject quickfix.MessageRejectError) { - fmt.Println("FromApp: ", msg) + fmt.Printf("FromApp: %s\n", msg.String()) return } func main() { + flag.Parse() + cfgFileName := "tradeclient.cfg" + if flag.NArg() > 0 { + cfgFileName = flag.Arg(0) + } + cfg, err := os.Open(cfgFileName) if err != nil { fmt.Printf("Error opening %v, %v\n", cfgFileName, err)