Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions cmd/generate-fix/internal/generate.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package internal

import (
"flag"
"fmt"
"go/ast"
"go/parser"
Expand All @@ -11,6 +12,7 @@ import (
)

var (
useFloat = flag.Bool("use-float", false, "By default, FIX float fields are represented as arbitrary-precision fixed-point decimal numbers. Set to 'true' to instead generate FIX float fields as float64 values.")
tabWidth = 8
printerMode = printer.UseSpaces | printer.TabIndent
)
Expand Down
63 changes: 56 additions & 7 deletions cmd/generate-fix/internal/template_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,31 @@ import (
"github.com/quickfixgo/quickfix/datadictionary"
)

func checkFieldDecimalRequired(f *datadictionary.FieldDef) (required bool, err error) {
var globalType *datadictionary.FieldType
if globalType, err = getGlobalFieldType(f); err != nil {
return
}

var t string
if t, err = quickfixType(globalType); err != nil {
return
}

if t == "FIXDecimal" {
required = true
return
}

for _, groupField := range f.Fields {
if required, err = checkFieldDecimalRequired(groupField); required || err != nil {
return
}
}

return
}

func checkFieldTimeRequired(f *datadictionary.FieldDef) (required bool, err error) {
var globalType *datadictionary.FieldType
if globalType, err = getGlobalFieldType(f); err != nil {
Expand Down Expand Up @@ -37,20 +62,38 @@ func checkFieldTimeRequired(f *datadictionary.FieldDef) (required bool, err erro
}

func collectExtraImports(m *datadictionary.MessageDef) (imports []string, err error) {
//NOTE: the time package is the only extra import considered here
var timeRequired bool
var timeRequired, decimalRequired bool
for _, f := range m.Fields {
if timeRequired, err = checkFieldTimeRequired(f); timeRequired {
imports = []string{"time"}
if !timeRequired {
if timeRequired, err = checkFieldTimeRequired(f); err != nil {
return
}
}

if !decimalRequired {
if decimalRequired, err = checkFieldDecimalRequired(f); err != nil {
return
}
}

if decimalRequired && timeRequired {
break
} else if err != nil {
return
}
}

if timeRequired {
imports = append(imports, "time")
}

if decimalRequired {
imports = append(imports, "github.com/shopspring/decimal")
}

return
}

func useFloatType() bool { return *useFloat }

func quickfixValueType(quickfixType string) (goType string, err error) {
switch quickfixType {
case "FIXString":
Expand All @@ -63,6 +106,8 @@ func quickfixValueType(quickfixType string) (goType string, err error) {
goType = "time.Time"
case "FIXFloat":
goType = "float64"
case "FIXDecimal":
goType = "decimal.Decimal"
default:
err = fmt.Errorf("Unknown QuickFIX Type: %v", quickfixType)
}
Expand Down Expand Up @@ -141,7 +186,11 @@ func quickfixType(field *datadictionary.FieldType) (quickfixType string, err err
case "PERCENTAGE":
fallthrough
case "FLOAT":
quickfixType = "FIXFloat"
if *useFloat {
quickfixType = "FIXFloat"
} else {
quickfixType = "FIXDecimal"
}

default:
err = fmt.Errorf("Unknown type '%v' for tag '%v'\n", field.Type, field.Tag())
Expand Down
18 changes: 16 additions & 2 deletions cmd/generate-fix/internal/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func init() {
"quickfixValueType": quickfixValueType,
"getGlobalFieldType": getGlobalFieldType,
"collectExtraImports": collectExtraImports,
"useFloatType": useFloatType,
}

baseTemplate := template.Must(template.New("Base").Funcs(tmplFuncs).Parse(`
Expand All @@ -33,10 +34,15 @@ func init() {
{{ define "fieldsetter" -}}
{{- $field_type := getGlobalFieldType . -}}
{{- $qfix_type := quickfixType $field_type -}}
{{- if eq $qfix_type "FIXDecimal" -}}
Set{{ .Name }}(value decimal.Decimal, scale int32) {
{{ template "receiver" }}.Set(field.New{{ .Name }}(value, scale))
}
{{- else -}}
Set{{ .Name }}(v {{ quickfixValueType $qfix_type }}) {
{{ template "receiver" }}.Set(field.New{{ .Name }}(v))
}
{{- end }}
{{- end }}{{ end }}

{{ define "groupsetter" -}}
Set{{ .Name }}(f {{ .Name }}RepeatingGroup){
Expand Down Expand Up @@ -191,6 +197,9 @@ package {{ .Package }}

import(
"time"
{{- range collectExtraImports .MessageDef }}
"{{ . }}"
{{- end }}

"github.com/quickfixgo/quickfix"
"{{ importRootPath }}/field"
Expand Down Expand Up @@ -275,7 +284,7 @@ package field
import(
"github.com/quickfixgo/quickfix"
"{{ importRootPath }}/tag"

{{ if eq useFloatType false}} "github.com/shopspring/decimal" {{ end }}
"time"
)

Expand All @@ -298,6 +307,11 @@ func New{{ .Name }}NoMillis(val time.Time) {{ .Name }}Field {
return {{ .Name }}Field{ quickfix.FIXUTCTimestamp{ Time: val, NoMillis: true } }
}

{{ else if eq $base_type "FIXDecimal" }}
//New{{ .Name }} returns a new {{ .Name }}Field initialized with val and scale
func New{{ .Name }}(val decimal.Decimal, scale int32) {{ .Name }}Field {
return {{ .Name }}Field{ quickfix.FIXDecimal{ Decimal: val, Scale: scale} }
}
{{ else }}
//New{{ .Name }} returns a new {{ .Name }}Field initialized with val
func New{{ .Name }}(val {{ quickfixValueType $base_type }}) {{ .Name }}Field {
Expand Down
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ToApp notifies you of application messages that you are being sent to a counterp

FromAdmin(message Message, sessionID SessionID) MessageRejectError

FromAdmin notifies you when an administrative message is sent from a counterparty to your FIX engine. This can be usefull for doing extra validation on logon messages such as for checking passwords.
FromAdmin notifies you when an administrative message is sent from a counterparty to your FIX engine. This can be useful for doing extra validation on logon messages such as for checking passwords.

FromApp(msg Message, sessionID SessionID) MessageRejectError

Expand Down
Loading