Table of contents
FIX (a shorthand for Financial Information eXchange) is a widely adopted electronic communications protocol used for real-time exchange of information related to trading and markets. FIX connects the global ecosystem of venues, asset managers, banks/brokers, vendors and regulators by standardizing the communication among participants. FIX is a public-domain specification owned and maintained by FIX Protocol, Ltd (FPL).
SimpleFix Go is an open-source library that allows you to quickly integrate FIX messaging into your environment. The library is entirely written in Go, making it perfect for solutions powered by this programming language. SimpleFix Go supports any FIX API version. To learn about specifics of various FIX protocol versions, refer to the OnixS website.
You can provide your own extensions to SimpleFix Go and create a custom FIX dialect. This guide explains the basics of SimpleFix Go installation and provides examples illustrating how to configure and customize the library according to your requirements.
- Adding custom fields to the FIX protocol
- Adding custom messages to the FIX protocol
- Adding custom types to the FIX protocol
- Built-in session pipelines features
- Built-in Acceptor (for the server side)
- Built-in Initiator (for the client side)
- Validation of incoming messages
- Validation of outgoing messages
- A demo server complete with mock data
- Anything missing? Let us know!
To install SimpleFix Go, download the library by executing the following command:
$ go get -u github.com/b2broker/simplefix-go
- Install the Generator if you want to use your own XML schema providing a custom set of FIX messaging options:
$ cd $GOPATH/src/github.com/b2broker/simplefix-go && go install ./...
The Generator is used to define the structure of FIX messages, as well as specify their tags and define message type constants and methods required to support any FIX API version.
Examples of code produced by the Generator can be found in the ./tests directory containing an automatically generated Go library based on a stripped-down FIX version 4.4. The library code is generated according to a scheme located in the ./source directory.
The following code generates a FIX library based on an XML schema defining the library structure:
fixgen -o=./fix44 -s=./source/fix44.xml -t=./source/types.xml
After executing this command, the generated library code will be located in the ./fix44 directory.
To create a custom FIX messaging library, prepare two XML files and specify the following parameters for the fixgen
command:
-o
— the output directory
-s
— the path to the main XML schema
-t
— the path to an XML file specifying value type mapping and informing the Generator about proper type casting (although the original FIX protocol features a lot of different value types, Go uses a smaller set of types that should be mapped to the FIX API)
Sample XML files are located in the ./source directory. You can use the existing files or modify them as required.
In this section, you will learn how to specify the session options and start a new FIX session as a client or as a server.
The following sample code illustrates how to use a message builder to create various standard messages, as well as define fields and message tags required for FIX session pipelines. The fixgen
command will generate the required structure in almost no time.
// In this code, fixgen is your generated FIX package:
var sessionOpts = session.Opts{
MessageBuilders: session.MessageBuilders{
HeaderBuilder: fixgen.Header{}.New(),
TrailerBuilder: fixgen.Trailer{}.New(),
LogonBuilder: fixgen.Logon{}.New(),
LogoutBuilder: fixgen.Logout{}.New(),
RejectBuilder: fixgen.Reject{}.New(),
HeartbeatBuilder: fixgen.Heartbeat{}.New(),
TestRequestBuilder: fixgen.TestRequest{}.New(),
ResendRequestBuilder: fixgen.ResendRequest{}.New(),
},
Tags: &messages.Tags{
MsgType: mustConvToInt(fixgen.FieldMsgType),
MsgSeqNum: mustConvToInt(fixgen.FieldMsgSeqNum),
HeartBtInt: mustConvToInt(fixgen.FieldHeartBtInt),
EncryptedMethod: mustConvToInt(fixgen.FieldEncryptMethod),
},
AllowedEncryptedMethods: map[string]struct{}{
fixgen.EnumEncryptMethodNoneother: {},
},
SessionErrorCodes: &messages.SessionErrorCodes{
InvalidTagNumber: mustConvToInt(fixgen.EnumSessionRejectReasonInvalidtagnumber),
RequiredTagMissing: mustConvToInt(fixgen.EnumSessionRejectReasonRequiredtagmissing),
TagNotDefinedForMessageType: mustConvToInt(fixgen.EnumSessionRejectReasonTagNotDefinedForThisMessageType),
UndefinedTag: mustConvToInt(fixgen.EnumSessionRejectReasonUndefinedtag),
TagSpecialWithoutValue: mustConvToInt(fixgen.EnumSessionRejectReasonTagspecifiedwithoutavalue),
IncorrectValue: mustConvToInt(fixgen.EnumSessionRejectReasonValueisincorrectoutofrangeforthistag),
IncorrectDataFormatValue: mustConvToInt(fixgen.EnumSessionRejectReasonIncorrectdataformatforvalue),
DecryptionProblem: mustConvToInt(fixgen.EnumSessionRejectReasonDecryptionproblem),
SignatureProblem: mustConvToInt(fixgen.EnumSessionRejectReasonSignatureproblem),
CompIDProblem: mustConvToInt(fixgen.EnumSessionRejectReasonCompidproblem),
Other: mustConvToInt(fixgen.EnumSessionRejectReasonOther),
},
}
The Initiator is a FIX API client that connects to an existing server.
The default Initiator implementation can be found in the ./initiator/main.go file.
The Acceptor is a listener that accepts and handles client connection requests. According to the FIX protocol, the Acceptor can be both a provider and receiver of data, meaning that it can send requests to the clients as well as read data streams received from them.
The default Acceptor implementation can be found in the ./acceptor/main.go file.
The SimpleFix library features a default session package which provides all the necessary functionality for the standard FIX API pipelines, such as authentication, logging out, heartbeats, message rejects and handling of typical errors. For this reason, if you want to customize the default messages, such as Logon <A>
or Heartbeat <0>
, you should configure the Session
structure in one of the following ways:
-
by integrating the existing structure into your custom procedure by way of composition, or simply copying the existing structure and modifying it in your client code
-
by modifying the message builder to account for the messages that you want to customize
The standard Session
structure accepts each MessageBuilder
instance as an auto-generated Opts
field. Each message builder is an interface, which means that you can create a custom builder, and the library will use it as the default one.
For example, if you want to add a new CounterPartyID
field (tag number 22000) to you Logon
message, you should modify your XML schema by adding a new field to the fields
section and to your custom Logon
message:
<fix>
. . .
<messages>
<message name='Logon' msgcat='admin' msgtype='A'>
. . .
<field name='CounterPartyID' required='Y'/>
...
</message>
</messages>
. . .
<fields>
<field number="22000" name="CounterPartyID" type="STRING"/>
</fields>
. . .
</fix>
While the rest of the code is generated by fixgen
, you should specify this field manually using a custom builder:
// Your FIX package is generated by fixgen:
type CustomLogon struct {
*fixgen.Logon
}
func (cl *CustomLogon) Build() messages.LogonBuilder {
l := cl.Build()
l.SetFieldCounterParty(os.Getenv("COUNTER_PARTY_ID"))
return l
}
After this, you can use your CustomLogon
structure (with a new field added to it) as a LogonBuilder
in the default FIX API pipelines.