Source: Creditease College, creditease.cn/ Author: Jiang Yongnian

define

FIX protocol is an open protocol organized and provided by THE International FIX Association, which aims to promote the process of electronization of international trade and establish real-time electronic communication protocols among various participants, including investment managers, brokers, buyers and sellers. The goal of FIX protocol is to format all kinds of securities and financial business requirements into a functional process that can be described by computer language, and exchange formats uniformly on each service functional interface to facilitate the connection of each functional module.

Working Principle of protocol

Communication model and basic concepts

Communication model

  • Initiator: Indicates the Initiator that establishes a communication link and initiates a session by sending an initial Logon message.
  • Acceptor: indicates the Acceptor of a FIX session. Responsible for performing the first level of authentication and for formally declaring that the connection request has been accepted through the transmission of Logon messages.
  • Principle: The Initiator is Initiator, and the Acceptor is Acceptor.
  • In the standard mode, the gateway is the Acceptor and the client is the Initiator.

Fix connection

  • The FIX connection consists of three parts: logon login, Message Exchange message transfer, and logout.
    • Logon login

Fix session

  • A FIX session consists of one or more FIX Connections. A FIX session can have multiple logins.

The serial number

  • All FIX messages are identified by a unique sequence number. The sequence number is initialized to 1 at the start of each FIX session and increments throughout the session. Monitoring serial numbers enables session participants to identify and process missing messages, enabling rapid application synchronization when reconnecting within a FIX session.
  • Each session establishes an independent set of receive and send sequences. The session participant maintains a sequence assigned to the sent message and a message block gap sequence number that monitors the received message.

The heartbeat

  • During message interaction, the FIX application periodically generates Heartbeat Heartbeat messages. The heartbeat message can monitor communication link status and identify gaps in received serial numbers. The interval for sending Heartbeat is defined by the session initiator using the HeartBtInt field in the Logon message.
  • The Heartbeat Heartbeat message interval should be reset after each message is sent, that is, after a message is sent, a Heartbeat message is sent if no other messages are sent within a given interval of time. The value of HeartBtInt should be agreed by both parties of the session, defined by the session initiator, and confirmed by the session receiver through the Logon message. The same HeartBtInt is used by both sides of the session, the initiator of the login and the receiver of the login.

Data integrity check

  • The integrity of message data content can be verified in two ways: message length and code checking.
  • The program calculates the number of characters from BodyLength field to CheckSum marker (” 10= “) and compares the message length of BodyLength field to complete the integrity effect.
  • ChekSum completeness check is obtained by calculating the base 2 of each character from the field “8=”, including the delimiter immediately following the CheckSum marker field and comparing it with the CheckSum.
  • A FIX message checksum is obtained by calculating the sum of each byte of the message to the ChechSum field (but not included). The checksum is then converted to mod 256 digits for transmission and comparison. The checksum is computed after all encryption operations.
  • Verification code:
Example: 8= fix.4.29 = 735 =A34=149=CLIENT52=20181119-10:42:48.76856=SERVER98=0108=30141=Y10=208 3, char *GenerateCheckSum(char *buf, char *buf, char *buf) long bufLen ) { static char tmpBuf[ 4 ]; long idx; unsigned int cks;for( idx = 0L, cks = 0; idx < bufLen; cks += (unsigned int)buf[ idx++ ] ); Sprintf (tmpBuf, "%03d", (unsigned int)(CKS % 256));return( tmpBuf );
}
Copy the code

Message to confirm

  • The FIX protocol does not support confirmation of a single message. The method of monitoring message time slot is used for message recovery and verification.
  • Normal data transmission (without a single message acknowledgement) is error identified by message sequence gaps. Each message is identified by a unique serial number. The receiver application is responsible for monitoring the received message sequence number to identify message gaps and generate retransmission requests.
  • Each FIX participant must maintain two serial numbers for the FIX session, a receive sequence number and a send sequence number, both of which are initialized to 1 when the FIX session is established. Each message is assigned a unique sequence number value that is incremented after the message is sent. In addition, each received message has a unique sequence number, and the receive sequence number counter is incremented after each message is received.
  • Error correction must be taken when the received serial number does not match the desired correct serial number.

encryption

  • The encryption algorithm is negotiated by both parties.
  • Any field of a message can be encrypted and placed in the SecureData field. However, some of the displayed flag fields must be transmitted in clear text. To ensure integrity, the plaintext field can be repeated in the SecureData field.
  • When using encryption, it is recommended, but not required, that all message bodies be encrypted. If part of the repeating group data in a message is to be encrypted, the repeating group must be fully encrypted.
  • Pre-negotiated encryption algorithms are declared in Logon messages.

Custom fields

  • FIX Provides maximum flexibility for users. The FIX protocol allows users to customize domains. These domains are implemented and applied between agreed participants, and care should be taken to avoid conflicts.
  • Tag numbers from 5000 to 9999 are reserved for user – defined fields. These tag values are used for the information exchange of the enterprise alliance. You can sign up through FIX.
  • More than 10000 are reserved for internal use in a single enterprise. No registration required.

The message format

The data type

Int, float, single character char, Boolean, String, data

The domain

Common domain

Tag FieldName (Domain name) note
8 BeginString Start string, version of the FIX protocol
9 BodyLength The length of the message
35 MsgType Message type: for example, F=Order Cancel Request
11 ClOrdID Client order ID
37 OrderID ID of the server order
41 OrigClOrdID ID of the original client order
54 Side Type of buying and selling. Example: 1 = Buy, 2 = Sell
55 Symbol Ticker symbol. For example: the YRD
10 CheckSum Check code

The domain of grammar

  • The header should begin, followed by the body, and finally the tail;
  • The order of the first three fields of the header cannot be changed: the start string (Tag =8), the body length (Tag =9), and the message type (Tag =35).
  • The last field at the end of the message should be the checksum field (Tag=10);
  • In a repeating group, the order in which the fields appear should follow the order in which the repeating group was defined in the message or component;
  • No field other than the repeating group domain can be repeated in a message.

Security and Encryption

  • Because messages may be transmitted and exchanged on public networks or insecure networks, sensitive data must be encrypted.
  • The specific encryption method depends on the agreement between the two parties.
  • Any field in a message, except for some fields that need to be identified publicly, can be encrypted and placed in a SecureData field. Of course, these encrypted fields can also retain the plaintext representation.
  • When you decide to use an encryption scheme, you can encrypt all fields within the message body. If part of the message’s repeating group needs to be encrypted, then the entire repeating group is required to be encrypted.
  • The protocol also provides domains to support security technologies such as digital signature, key exchange, and text encryption.

The message

The message header

Each session or application message has a header that specifies the message type, length, destination, sequence number, starting point, and time.

Tag The domain name necessary instructions
8 BeginString Y Start string, value: fix.4.2 (non-encrypted, first field of message)
9 BodyLength Y Message body length (unencrypted, second field of message)
35 MsgType Y Message type (non-encryptible, third field of message)
49 SenderCompID Y Sender code (unencrypted, sender identifier)
56 TargetCompID Y Recipient code (unencrypted, recipient identifier)
115 OnBehalfOfCompID N The original sender identifier (encrypted) used to send through a third party.
128 DeliverToCompID N Final recipient identifier (encrypted) for sending via a third party.
90 SecureDataLen N Length of ciphertext data
91 SecureData N Ciphertext data (following ciphertext data length field)
34 MsgSeqNum Y Message sequence number (encrypted), which can be set to a fixed value, such as 0, if both parties do not use FIX session mechanism.
50 SenderSubID N Sender sub-identifier (encryptable)
142 SenderLocationID N Send square identifier (encryptable)
57 TargetSubID N Recipient sub-identifier (encryptable)
143 TargetLocationID N Recipient bit identifier (encryptable)
116 OnBehalfOfSubID N Original sender sub-identifier (encryptable)
144 OnBehalfOfLocationID N Initially send square identifier (encryptable)
129 DeliverToSubID N Final recipient subidentifier (encryptable)
145 DeliverToLocationID N Final recipient bit identifier (encryptable)
43 PossDupFlag N May repeat the flag, when repeated send, make this flag. (Encrypted)
97 PossResend N Possible reissue of flags. (Encrypted)
52 SendingTime Y Send time (encrypted)
122 OrigSendingTime N Original send time (encrypted)
347 MessageEncoding N The character encoding type of the Encoded field in the message (non-ASCII)
369 LastMsgSeqNumProcesse d N Last processing message sequence number (encryptable)
370 OnBehalfOfSendingTime N Original sending time (UTC time)

The message the tail

Each message (session or application message) has a message tail and terminates at that point. The message tail can be used to separate multiple messages and contains a 3-digit checksum value.

Tag The domain name necessary instructions
93 SignatureLength N Length of digital signature (not encrypted)
89 Signature N Digital signature (non-cryptographic)
10 CheckSum Y Checksum, the last field of a message. (Not encrypted)

New order message (MsgType=D)

For an order message with the PossResend flag set in the message header, the trade customer order number (ClOrdID) should be used to verify that the order has been received, and the order parameters (buy and sell direction, security code, quantity, etc.) should be checked as well. If the order was previously received, the order status should be responded with an execution report message. If it has not been received before, it responds to the order confirmation with an execution report message.

Tag The domain name necessary instructions
Standard header Y MsgType=D
11 ClOrdID Y The trading customer order number is required within the valid trading day of the order
109 ClientID Y Customer fund account
1 Account Y Customer transaction code
110 MinQty N Minimum volume.
55 Symbol Y Futures contract code
167 SecurityType N FUT = futures
200 MaturityMonthYear N The year and month used to specify the maturity of the futures
205 MaturityDay N The expiration date of a futures contract and is used in conjunction with expiration month
207 SecurityExchange Y Used to designate an exchange
77 OpenClose Y Indicate opening and closing of a position
8009 HedgeFlag Y Speculative hedging sign
8010 TouchCondition N The trigger condition
54 Side Y Business direction
38 OrderQty N Entrust the hand count
60 TransactTime Y Order origination time
40 OrdType Y Order type
44 Price N Price (valid for limit price order)
423 PriceType N Price type
99 StopPx N Stop price
15 Currency N currency
59 TimeInForce N Time when a new order takes effect. The default value is the same day
168 EffectiveTime N Used to specify when an order is valid
432 ExpireDate N Conditional when TimeInForce = valid before a certain date (GTD) and no expiration time (ExpireTime) is specified
126 ExpireTime N Used conditionally when the effective time (TimeInForce) = valid before a certain date (GTD) and no expiration date is specified
8096 MacNetInfo N Client’s machine network information
Standard message tail Y

Execution Report message (MsgType=8)

  • Order confirmation
  • Confirmation of change of order status (such as confirmation of withdrawal)
  • Return on delivery of orders
  • Order is rejected
Tag The domain name necessary instructions
Standard header Y MsgType=8
37 OrderID Y The commission number of the futures company must be unique on the same trading day
11 ClOrdID N Transaction customer order Number. If it is a strong flat return, the value is the unique identifier of the trading day starting with NONE
41 OrigClOrdID N The original transaction customer order number indicating the ClOrdID of the cancelled order
17 ExecID Y The execution number of the futures company shall be unique within the effective trading day of the order
150 ExecType Y Perform type
39 OrdStatus Y The order status
103 OrdRejReason N Required when an order is rejected
109 ClientID Y Customer fund account
1 Account Y Customer transaction code
55 Symbol Y Futures contract code
167 SecurityType N FUT = futures
200 MaturityMonthYear N Due to time
205 MaturityDay N Due date
207 SecurityExchange Y Used to designate an exchange
77 OpenClose N Indicate opening and closing of a position
54 Side Y Business direction
38 OrderQty Y Entrust the hand count
40 OrdType N Order type
44 Price N The order price
99 StopPx N Stop price
59 TimeInForce N Time when a new order takes effect. The default value is the same day
15 Currency N currency
32 LastShares N Last Transaction (Last Transaction)
31 LastPx N Last transaction price (last transaction price)
30 LastMkt N Last traded market
151 LeavesQty Y Remaining quantity of order
14 CumQty Y The total number of clinch a deal
6 AvgPx Y Average transaction price
60 TransactTime N Execution report Time
381 GrossTradeAmt N Total transaction amount
110 MinQty N Minimum volume
8500 OrderEntryTime N Order declaration time
8093 DeclarationID N Declaration for no.
8094 TradeID N Set number
Standard message tail Y

Order Status request message (MsgType=H)

An order status request is used to request the status of an order from a trade server, and the trade server returns the order status by executing a report message.

Tag The domain name necessary instructions
Standard header Y MsgType=H
37 OrderID Y The commission number of the futures company must be unique on the same trading day
11 ClOrdID Y Transaction customer order Number
109 ClientID Y Customer fund account
1 Account Y Customer transaction code
55 Symbol Y Futures contract code
207 SecurityExchange Y Used to designate an exchange
167 SecurityType N FUT = futures
200 MaturityMonthYear N The year and month used to specify the maturity of the futures
205 MaturityDay N The expiration date of a futures contract and is used in conjunction with expiration month
54 Side Y Business direction
Standard message tail Y

Cancellation message (MsgType=F)

A retraction message is used to cancel all remaining quantities of an order. The cancellation message is also given a ClOrdID, which can be viewed as another order. If rejected, the ClOrdID of the retraction rejection message is placed in the ClOrdID of the retraction message, and the ClOrdID of the original order is placed in the OrigClOrdID field. ClOrdID is guaranteed to be unique.

Tag The domain name necessary instructions
Standard header Y MsgType=F
41 OrigClOrdID Y The original transaction customer order number indicating the ClOrdID of the cancelled order
37 OrderID Y The commission number of the futures company must be unique on the same trading day
11 ClOrdID Y Transaction customer order Number
109 ClientID Y Customer fund account
1 Account Y Customer transaction code
55 Symbol Y Futures contract code.
167 SecurityType N Source of securities code
200 MaturityMonthYear N FUT = futures
205 MaturityDay N Date of maturity
207 SecurityExchange Y Futures maturity date
54 Side Y Business direction
60 TransactTime Y Order origination time
40 OrdType Y Order type
38 OrderQty Y Entrust the hand count
8093 DeclarationID N Declaration for no.
58 Text N
Standard message tail Y

Withdraw reject message (MsgType=9)

This message is used to reject a retraction message. After receiving the withdrawal order, the trading service party finds that it cannot be executed (the completed order cannot be changed, etc.), it will send the withdrawal order to reject it. When a withdrawal is rejected, the withdrawal rejection message applies ClOrdID to indicate the ClOrdID of the withdrawal and OrigClOrdID to indicate the last order accepted before (unless the rejection reason is “unknown order”).

Tag The domain name necessary instructions
Standard header Y MsgType=9
37 OrderID Y The commission number of the futures company must be unique on the same trading day
11 ClOrdID Y Transaction customer order Number
41 OrigClOrdID Y The original transaction customer order number indicating the ClOrdID of the cancelled order
39 OrdStatus Y The order status
109 ClientID Y Customer fund account
1 Account Y Customer transaction code
60 TransactTime N Order origination time
434 CxlRejResponseTo N Retraction Reject response type
102 CxlRejReason N Reason for rejection of withdrawal order
58 Text N
Standard message tail Y

FIX configuration

  • SESSION Configuration
configuration describe Valid values The default
BeginString The FIX version number used by the session (start string for sending and receiving messages) Fixt.1.1, fix.4.4, fix.4.3, fix.4.2, fix.4.1, fix.4.0
SenderCompID Session to define the ID of the party A case-sensitive string
SenderSubID The local sub-ID number associated with the session (optional) A case-sensitive string
SenderLocationID Local locationID number associated with the session (optional) A case-sensitive string
TargetCompID ID of the peer in this session A case-sensitive string
TargetSubID SubID of the other party in this session (optional) A case-sensitive string
TargetLocationID Peer locationID in this session (optional) A case-sensitive string
SessionQualifier Additional determiners used to disambiguate and ensure the uniqueness of the conversation A case-sensitive string
DefaultApplVerID Only FIXT1.1 (or later) is required. Ignore transfers of earlier versions. Specifies the version ID of the default application for the session. Enumeration of ApplVerID (see ApplVerID field for details), or the default BeginString. FIX.5.0SP2, FIX.5.0SP1, FIX.5.0, FIX.4.4, FIX.4.3, FIX
ConnectionType Define the role of the client in the session as acceptor or initiator Initiator and the acceptor
StartTime The valid session start time of the trading day when the FIX session is activated The UTC time is in HH:MM:SS format
EndTime Session expiration time on the trading day. The FIX session will be stopped The UTC time is in HH:MM:SS format
StartDay For a one-week session configuration, the first day the session starts. Used in conjunction with STARTTIME. Any abbreviation for the day of the week is valid (e.g.,Mo, mon, mond, monda,Monday are valid)
EndDay For a one-week session configuration, the last day of the end of the one-week session. Used in conjunction with EndTime. Any abbreviation for the day of the week is valid (e.g.,Mo, mon, mond, monda,Monday are valid)
MillisecondsInTimeStamp Whether to add milliseconds to the timestamp. Fix.4.2 and later versions are available. Y, N Y
ResetOnLogon Whether to reset the serial number when receiving a login request. Only for Acceptor Y, N N
ResetOnLogout Whether to reset the serial number during normal logout Y, N N
ResetOnDisconnect Whether to reset the serial number to 1 after the connection is abnormally disconnected Y, N N
RefreshOnLogon Determines whether session state should be restored when logging in from the persistence layer. Useful when creating hot failover sessions. Y, N N
EnableLastMsgSeqNumProcessed Whether to add the serial number of the last message to the header (optional TAG369). Y, N N
MaxMessagesInResendRequest Sets the maximum number of messages that can be resent at a time. Any integer greater than 0. Use 0 for infinity (the default). 0
SendLogoutBeforeDisconnectFromTimeout Specifies whether to send the logout message before disconnecting due to a timeout Y, N N
IgnorePossDupResendRequests Whether to ignore a replay request when PossDupFlag (Tag 43) is set to true Y, N N
  • Verify the configuration
configuration describe Valid values The default
UseDataDictionary Tells the session whether or not to use a data dictionary. If you’re going to use Repeating Group, you have to use DataDictionary. Y, N Y
DataDictionary This configuration only works with versions older than Fixt.1.1. Refer to the TransportDataDictionary and AppDataDictionary configurations in Fixt.1.1 for details. Fix44.xml, fix43.xml, fix42.xml, fix41.xml, fix40.xml
TransportDataDictionary The XML definition file is used to validate incoming administrative messages. If DataDictionary is not provided, only basic message validation is done. This configuration is only used for fixt.1.1 (or later) sessions. XML FIXT1.1.
AppDataDictionary XML definition files for validating application-layer messages. Only valid for fixt.1.1 (or later) sessions. See DataDictionary (fix.4.0 through Fix.4.4) for more information. This configuration allows you to specify a custom application data dictionary for each session. This configuration only works with Fixt.1.1 or newer transport protocols. When using FIXT transport, this configuration can be used as a prefix to specify data dictionaries for multiple applications. Such as: DefaultApplVerID= fix.4.2 # For default Application version ID AppDataDictionary= fix42.xml # For nondefault Application Version ID # Use BeginString suffix for app version AppDataDictionary. FIX. 4.4 = FIX44. XML A valid XML data dictionary file. XML, fix50SP1. XML, fix50.xml, fix44.xml, fix43.xml, fix42.xml, fix41.xml, and fix40.xml
ValidateFieldsOutOfOrder If set to N, field placement errors (for example, the body field is in the header area, or the header field is in the Body area) will not be rejected. Used to connect to systems with less stringent field requirements. Y, N Y
ValidateFieldsHaveValues If set to N, fields with no value will not be rejected. Used to connect to the system improperly sending empty labels. Y, N Y
ValidateUserDefinedFields If set to N, user-defined fields will not be rejected, even if they are not defined in the data dictionary or do not appear in the message. Y, N Y
  • Initiator
configuration describe Valid values The default
ReconnectInterval The time interval (seconds) between attempts to reconnect. This parameter is used only as initiator. Positive integer 30
HeartBtInt Heartbeat interval (seconds). This parameter is used only as initiator. Positive integer
LogonTimeout Login timeout interval (seconds) Positive integer 10
LogoutTimeout Logout Timeout Interval (seconds) Positive integer 2
SocketConnectPort Socket Service port for establishing a session. Only used for initiator Positive integer
SocketConnectHost Connect to the host. Initiator only X.X.X.X indicates the IP address or domain name
SocketConnectPort A set of alternate Socket ports used for connection session failover. N is a positive integer. SocketConnectPort1 SocketConnectPort2… Must be contiguous and have a SocketConnectHost array matching it Positive integer
SocketConnectHost A group of alternate Socket service hosts used for connection session failover. N is a positive integer. SocketConnectHost1, SocketConnectHost2… Must be contiguous and have a SocketConnectPort array matching it X.X.X.X indicates the IP address or domain name
SocketNodelay Whether the connection disables the Nagle algorithm. Configure the node definition at [DEFAULT]. Y, N Y
ReconnectInterval The time interval (seconds) between attempts to reconnect. This parameter is used only as initiator. Positive integer 30
  • Acceptor
configuration describe Valid values The default
SocketAcceptPort Listening access Connects to the Socket port. Only used for acceptor A positive integer, a valid, open socket port
SocketAcceptHost The host that listens for the Socket service of the access connection. If not, acceptor listens on all network ports (0.0.0.0) A valid IP address in X.X.X.X format 0.0.0.0
SocketNodelay Whether the connection disables the Nagle algorithm. Configure the node definition at [DEFAULT]. Y, N Y
  • Storage
configuration describe Valid values The default
PersistMessages If set to N, messages are not saved. This will force QuickFix to always send GapFills instead of resending the message. If you know you will never need to resend messages, use this configuration. Useful market data flow. Y, N Y
  • File Storage
configuration describe Valid values The default
FileStorePath Directory of files where serial numbers and messages are stored. Valid file storage directory, must have write permission.
  • Logging
configuration describe Valid values The default
FileLogPath Directory for storing logs. Valid file storage directory, must have write permission.

FIX the development

FIX the engine

  • Official website: FIX Engine
  • Github: QFJ Github Repository

DEMO

  • Acceptor configuration file
# define the default configuration of the session (default node)
[DEFAULT]
FileStorePath=store
FileLogPath=logConnectionType=acceptor ReconnectInterval=60 SenderCompID=SERVER ResetOnDisconnect=Y ResetOnLogout=Y ResetOnLogon=Y [SESSION] BeginString= fix.4.2 TargetCompID=CLIENT StartTime=00:00:00 EndTime=23:59:59 HeartBtInt=30 SocketAcceptHost = 127.0.0.1 SocketAcceptPort = 6666 DataDictionary = FIX42. The XMLCopy the code
  • Initiator configuration file
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=60
FileLogPath=logFileStorePath=store StartTime=00:00:00 EndTime=23:59:59 HeartBtInt=30 ResetOnDisconnect=Y ResetOnLogout=Y ResetOnLogon=Y [SESSION] BeginString= fix.4.2 SenderCompID=CLIENT TargetCompID=SERVER SocketConnectPort=6666 SocketConnectHost = 127.0.0.1 DataDictionary = FIX42. XMLCopy the code
  • FixServer
package com.app.fix;

import quickfix.*;

/** * The service starts the main class (thread) */
public class FixServer {
    private static ThreadedSocketAcceptor acceptor = null;

    /** * Specifies the configuration file to start@param propFile
     * @throws ConfigError
     * @throws FieldConvertError
     */
    public FixServer(String propFile) throws ConfigError, FieldConvertError {
        // Set the configuration file
        SessionSettings settings = new SessionSettings(propFile);

        // Set an APPlication
        Application application = new FixServerApplication();

        /** ** quickfix.MessageStore has two implementations. Quickfix. JdbcStore quickfix. FileStore. * JdbcStoreFactory responsible for creating JdbcStore, FileStoreFactory is responsible for creating FileStorequickfix * File storage is used by default because file storage is efficient. * /
        MessageStoreFactory storeFactory = new FileStoreFactory(settings);

        LogFactory logFactory = new FileLogFactory(settings);

        MessageFactory messageFactory = new DefaultMessageFactory();

        acceptor = new ThreadedSocketAcceptor(application, storeFactory, settings, logFactory, messageFactory);

    }

    private void startServer(a) throws RuntimeError, ConfigError {
        acceptor.start();
    }

    /** * Test the main method ** used locally@param args
     * @throws FieldConvertError
     * @throws ConfigError
     */
    public static void main(String[] args) throws ConfigError, FieldConvertError {
        FixServer fixServer = new FixServer("res/acceptor.config"); fixServer.startServer(); }}Copy the code
  • FixServerApplication
package com.app.fix;

import quickfix.Application;
import quickfix.DoNotSend;
import quickfix.FieldNotFound;
import quickfix.IncorrectDataFormat;
import quickfix.IncorrectTagValue;
import quickfix.Message;
import quickfix.MessageCracker;
import quickfix.RejectLogon;
import quickfix.Session;
import quickfix.SessionID;
import quickfix.UnsupportedMessageType;
import quickfix.field.MsgType;

/**
 * 
 */
public class FixServerApplication extends MessageCracker implements Application {
    @Override
    protected void onMessage(Message message, SessionID sessionID) {
        try {
            String msgType = message.getHeader().getString(35);
            Session session = Session.lookupSession(sessionID);
            switch (msgType) {
                case MsgType.LOGON: / / login
                    session.logon();
                    session.sentLogon();
                    break;
                case MsgType.HEARTBEAT: / / the heart
                    session.generateHeartbeat();
                    break; }}catch(FieldNotFound e) { e.printStackTrace(); }}@Override
    public void onCreate(SessionID sessionId) {
        System.out.println("Call this method to create when the server starts");

    }

    @Override
    public void onLogon(SessionID sessionId) {
        System.out.println("Call this method when the client logs in successfully.");

    }

    @Override
    public void onLogout(SessionID sessionId) {
        System.out.println("Call this method when the client is disconnected");

    }

    @Override
    public void toAdmin(Message message, SessionID sessionId) {
        System.out.println("Call this method when sending session messages");

    }

    @Override
    public void toApp(Message message, SessionID sessionId) throws DoNotSend {
        System.out.println("Call this method when sending a business message");

    }

    @Override
    public void fromAdmin(Message message, SessionID sessionId)
            throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
        System.out.println("Call this method when a session type message is received");
        try {
            crack(message, sessionId);
        } catch(UnsupportedMessageType | FieldNotFound | IncorrectTagValue e) { e.printStackTrace(); }}@Override
    public void fromApp(Message message, SessionID sessionId)
            throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
        System.out.println("Call this method when a business message is received"); crack(message, sessionId); }}Copy the code
  • FixClient
package com.app.fix;

import quickfix.*;
import quickfix.field.*;
import quickfix.fix42.NewOrderSingle;

import java.io.FileNotFoundException;
import java.util.Date;

public class FixClient implements Application {

    private static volatile SessionID sessionID;

    @Override
    public void onCreate(SessionID sessionID) {
        System.out.println("OnCreate");
    }

    @Override
    public void onLogon(SessionID sessionID) {
        System.out.println("OnLogon");
        FixClient.sessionID = sessionID;
    }

    @Override
    public void onLogout(SessionID sessionID) {
        System.out.println("OnLogout");
        FixClient.sessionID = null;
    }

    @Override
    public void toAdmin(Message message, SessionID sessionID) {
        System.out.println("ToAdmin");
    }

    @Override
    public void fromAdmin(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon {
        System.out.println("FromAdmin");
    }

    @Override
    public void toApp(Message message, SessionID sessionID) throws DoNotSend {
        System.out.println("ToApp: " + message);
    }

    @Override
    public void fromApp(Message message, SessionID sessionID) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType {
        System.out.println("FromApp");
    }

    public static void main(String[] args) throws ConfigError, FileNotFoundException, InterruptedException, SessionNotFound {
        SessionSettings settings = new SessionSettings("res/initiator.config");

        Application application = new FixClient();
        MessageStoreFactory messageStoreFactory = new FileStoreFactory(settings);
        LogFactory logFactory = new ScreenLogFactory(true.true.true);
        MessageFactory messageFactory = new DefaultMessageFactory();

        Initiator initiator = new SocketInitiator(application, messageStoreFactory, settings, logFactory, messageFactory);
        initiator.start();

        while (sessionID == null) {
            Thread.sleep(1000);
        }

        final String orderId = "342";
        NewOrderSingle newOrder = new NewOrderSingle(new ClOrdID(orderId), new HandlInst('1'), new Symbol("YRD"),
                new Side(Side.BUY), new TransactTime(new Date()), new OrdType(OrdType.MARKET));
        Session.sendToTarget(newOrder, sessionID);
        Thread.sleep(5000); }}Copy the code