HOME  | DEMO  |  BUY NOW



    Application Fix Interface  (c) 2003 Octatec Ltd
   


The Application Fix Interface is a FIX Engine with a very simple Application Programming Interface (API) that is designed to make adding Fix Connectivity to your applications very easy; it is very easy to use and requires the programmer to implement only a few methods of a FixHandler Java class. The system includes a sample fix server program that can read  files written in a simple scripting language and thus makes testing your application very easy. 

For more information about the FIX Protocol see http://www.fixprotocol.org

Contents


System Components

There are 3 system components, a Fix Engine that is started automatically when needed, and 2 API jars that must be available on your classpath in order to access the Fix Engine

The system  creates an AFI FixEngine session passing in the name of a properties file. This causes the AFI FixEngine process to start up and read the properties file. using information it finds in the  file, it will connect, using tcp/ip sockets to an external Fix Engine. It will communicate with the User Application via a local socket. The User Application enters a Fix Message loop receiving and sending messages.


Getting Started

The following is the basic structure of the afitest sample application and demonstrates the standard pattern of an AFI application.
// AfiTest...

import com.octatec.aficlient.*;
import com.octatec.jfixgw.*;

// implement a Fixhandler

class MyFixHandler extends FixHandler {

public void onPreOpen()
{
     m_session.enableAutoSetComplete();
          // doing this means you do never need to call
          // m_session.setComplete() yourself
}

public void onFixMsg(String type, FixString msg)
{
     if( type.equals( FixConst.FIX_MSG_SomeType ) )
     {

    ...process the message contained in msg...

        // E.G. Use... 
       String value = msg.GetField(FixConst.FIX_FLD_SomeFieldType);

       m_session.setComplete(); // indicates the message is fully processed

        // maybe you now want to send a message

        FixString myMsg = new FixString();

    myMsg.addField(FixConst.FIX_FLD_SomeFld, "some value");

    ...add more fields as required...

        m_session.sendMsg(FixConst.FIX_MSG_SomeOtherType, myMsg);
           // in an actual application you must catch 
             // any exception thrown by this method

}

}
}
/*
** from your application's main method...
*/

LPCTSTR propFileName = "loopback";
    // loopback is a standard properties file supplied with the distribution, it
    // allows a fix client (namely afitest) to connect to the afisrv application

AfiApp app = new AfiApp(propFileName);
FixHandler handler = new MyFixHandler();

int result = app.startApp(handler);
           // the system will now create a FixSession
           // and call your Fixhandler's methods
           // NB: there is NO RETURN from this method unil
           // the Fix Session has ended - to run a Fix Session
           // in a worker thread, see below

If you want your Fix Session to be created in a worker thread, just use an AfiThreadedApp object as follows
// afisrv
/* from the main thread... */

AfiThreadedApp app = new AfiThreadedApp(propFileName);
FixHandler handler = new MyFixHandler();
int result = app.startThread(handler);
        // the fix session is created in a worker thread and your 
        // FixHandler’s methods are call from the worker thread -
        // you can use methods on the AfiThreadedApp object to
        // send messages to your worker thread

/* still from the main thread… */

app.sendThreadFixMsg(FixConst.FIX_MSG_SomeOtherType, myMsg);
        // send a Fix Message via the worker thread - you
        // Don’t have to use this method to send fix messages
        // in a muti-threaded app, if the structure of your 
        // application permits it, you can send them directly 
        // from the worker thread using m_session.sendMsg() 
        // just as you would for a single threaded app

// at some point, close the session

app.closeThread();


FixEngine Properties File

This properties file describes the Fix Engine session, in particular what IP address and port number to use, as well as local optional settings. You pass the full pathname of a properties file into the constructor of the AfiApp or AfiThreadedApp. If you pass in a file name rather than a full pathname, the file is assumed to reside in  /Octatec/afi/Home/configs on UNIX-based systems and 
C:\Program Files\Octatec\afi\configs (or under whatever  directory you chose during the installation) on WIN32 systems.

The properties file contains a list of  names =values  entries, all entries are case sensitive

The following entries define the fix session

host = hostname
The host name to which the AFI Fix Engine will connect. The AFI Fix Engine will attempt to connect to hostname as a client. If the name is local, the local system is used. If the hostname is specified as an asterisk, *, the Fix Gateway will act as a server, i.e. it will listen for incoming calls and accept the first one. Only the first incoming call will be accepted - multiple connections to clients is not supported within a single gateway process, however multiple gateway process are permitted. For added security, you can specify a server using *N.N.N.N, in this case, the server will only accept calls from IPaddress N.N.N.N (note: you must use the actual IPaddress and not a hostname when restricting clients in this way.)

port = n
This is the port to used by the Fix Gateway.
FixVersion MAJ.MIN
This can be used to set the fix version, the default is 4.0. Currently MAJmust be 4. As of writing Fix 4.2 is the latest release release, so MIN should only be 0, 1 or 2.

localId = local
This is the name of the local fix session and is used in the outgoing fix header
LocalSubId local_sub
This is the sub-name of the local fix session and is used in the outgoing fix header

targetId = testsrvr
This is the expected name of the remote fix engine

targetSubId = testsrvr_sub
This is the expected sub-name of the remote fix engine
NB: these 4 IDs are not hostnames, they just strings chosen by the 2 sides of the fix conversation. Both sides must each know the others IDs and  specify them correctly in the config file. If SubId's are not being used, they can be left out of the config file, or given values starting with a '#' character. If the gateway detects a mismatch of IDs during logon, it will logout from the remote, unless checkLogonSubIDs is set to 0

gmtOffset = n
This parameter allows you to set a ‘virtual’ time zone for the fix gateway. The client application will still see the local time-zone as normal but the Fix Engine process will see the timezone as GMT+n (n can be +ve or –ve). The real implication of this is that Fix Message headers will leave with the Virtual Timezone in the time-stamp and midnight will also be dictated by the Virtual Timezone; midnight is important for FIX 4.0 and FIX 4.1 (and even FIX 4.2, when sessions are being re-set automatically) since the Fix Session is automatically reset when a session is restarted after midnight. The default value is 99, if GmtOffset is 99, the Virtual Timezone is the same as the system timezone.

bufferSize = n
By default, buffer size is 1024, and the system will not let you set it below 512. If you expect to receive particularly long Fix Messages (larger than 1012 bytes) you can increase the size of the buffer used to read incoming messages here.

FIXML_addhdr = n
If this is 1, a <Header>…</Header> section is automatically added to your outgoing XML. This duplicates the information in the standard FIX header, and is part of the FIXML specification. If you set this flag true, you don’t have to worry about adding te FIXML header yourself. If you set this flag to 0, you can either add FIXML header information yourself or leave it out if that is what has been agreed locally. In all cases the standard FIX header is automatically included by the Fix Engine process and you shold not attempt to add header fields using FixString::AddField() .The default value of this field is 0.

FIXML_addroot = n
If you set this to 1, your outgoing XML will be automatically enclosed in  <FIXML><FIXMLMessage> … </FIXML></FIXMLMessage> tags, so you don’t have to worry about adding them yourselves. (Of course this is only appropriate if your XML payload is actually FIXML) The default value of this field is 0.

preferNIO = n
The default value value is 1. Your should not normally change this – you will only want to change this if you are implementing your own SocketI and/or ServerSocketI in order to use a 3rd party SSL provider, and their implementation dos not support ‘nio’in which case you can set this value to 0.

The following entries control optional behaviour of the fix gateway

NB: there are quite a few parameters here, but mostly, the deault values will be what you want.

confirmResendSpec = List_of_Msg_Types
This setting allows your application program to decide is a message should be resent or not. List_of_Msg_Types is a colon-separated list of message type that you do not want to be resent automatically if a resend is requested by the remote side, e.g. D:E. When a message that appears in this list needs to be resent, your application is asked if the message is to be resent, if you say no, a gap fill is sent instead. List_of_Msg_Types can be a single asterisk (*), in which case, resend confirmation is requested for all non-admin messages. By default all messages are always resent automatically (except admin messages, of course, which are always replaced with GapFills)

forwardHeartbeat = n
If  n is 1, heartbeats will be received by the user application through the FixClient::GetFixMsg() method, if 0, heartbeats are not delivered to the user application. This might be useful if your application needs to perform housekeeping actions at regular intervals. It is also a useful way for the gateway to detect if your application has crashed or not - the gateway will only detect that your application has crashed when it tries to send data to it. The default value is 1.

forwardLogon = n
If n is 1, logon messages will be received by the user application through the FixClient::GetFixMsg() method, if 0, logon messages are not delivered to the user application. The default value is 0. This translates to a call to onLogon(FixMsg msg) on the Fix Handler.

forwardLogout = n
If n is 1, logout messages will be received by the user application through the FixClient::GetFixMsg() method, if 0, logon messages are not delivered to the user application. The default value is 0. This translates to a call to onRemoteLogout(FixMsg msg) on the Fix Handler.

ForwardRejection n
If n is 1, rejection messages will be received by the user application through the FixClient::GetFixMsg() method, if 0, rejections are not delivered to the user application. The default value is 0.

tolerateRejection = n
If n is 0 rejections are always allowed, if n is > 0, that number defines how many rejections will be received before the Fix Engine automatically closes. The default value is 1, i.e. the gateway automatically closes after receiving one session level rejection. 

heartBtInt = n
The heart beat interval, in seconds, passed in the login message, this is 15 by default
AlwaysUseOpenEndedResend n
If the value of n is 1, resend requests are always open-ended, if the value is 0,  resend requests are terminated with the current required sequence number. the default value is 1.

supressNestedResendRequests = n
If n is 1, the sending of resend requests after just issuing a resend are suppressed for a maximum of ResendSupressionTimeout seconds. This parameter is designed to avoid the situation where the sender has buffered up a lot of messages, but the first message triggers a resend. In this situation, the 2nd message would also trigger a resend, as would all the messages in the buffer, resulting in a lot of resend requests arriving at the sender. After ResendSupressionTimeout seconds have elapsed, normal resend requesting behaviour is resumed. The default value is 1.

resendSupressionTimeout = n
This parameter controls the number of seconds for which the special behaviour is performed. The default is 10 seconds.

honourOutOfSeqResend = n
This flag allows special action to be taken when a deadlock situation arises. When both fix engines start up, and both discover the Logon message contains an invalid sequence number, both sides will issue resend requests, but both sides will ignore the others resend because it contains an invalid sequence number. If this flag is 0, no special action is performed, if it is 1, a resend request with an invalid sequence number is still processed, and the requested messages are resent, if it is -1, a resend request with an invalid sequence number is rejected and a logout is initiated. The default value is 1.

journalIncoming = n
If n is 1, incoming messages are saved in a journal, if 0, incoming messages are not journaled (The default value is 1). Outgoing messages are always journaled. The Incoming (Receive Journal) plays a part in ensuring messages do not get lost, so read the section abount SetComplete() before switching this off.

logDir = path
This value defined the log directory. The first character may be a % as in %/logs, in which case the % is replaced by the Installation Directory under WIN32 and by /Octatec/fixgw/Home under UNIX/Linux. NB: the directory must exist. A sub directory with the name YYYYMMDD is created in the log directory, and logs and journal files are saved here. The fix gateway should close down at least once every 24 hours so that a new log directory is allocated. Ideally, the fix gateway will be closed sometime before midnight, and restarted sometime after; however, if you plan to use manual session resets, as permitted  under FIX 4.2, this is not required. NOTE: the path cannot contain spaces, if you are on a WIN32 system and you're path does contain spaces, use the short-form of the path, if you are on a UNIX system, you could create a symbolic link (that doesn't contain spaces) to the directory. NOTE: If you are entering a path-name on a WIN32 system, you must use \\ (two backslashes) as the path separator.

clientLogDir = path
This entry defines where the client logs are placed. Client logs are less important than server logs, but still useful if you encounter problems. If this entry is not present, if this entry is not present, the logDir (above) is used. If this directory doesn’t exists, the application will display an error message and exit – it is better to know straight away that there is a problem rather than try and search for the non-existent log at some later date 

logLevel = n
This defined the level of logging, 0 is the least verbose and 2 is the most verbose. The default value is 2.

__debug__ = n
If this value is 1, debug logging mode is switched on, in this mode all log files are closed after each entry is written, and opened again as needed, in this way, the log files can always be viewed in all environments. NOTE: setting this to 1 will slow the system down; the default value is 0.

checkLogonSubIDs = n
If any of the IDs (TargetSubID etc) in the config file are blank or start with a hash (#), then the ID is not added to the Fix message that is sent. When we process a logon, the TargetID must match the in-coming SenderID, and the target SubID must match the incoming sender SubID unless the TargetSubID is blank or starts with a hash (#), in which case, we are 'not' processing SubIDs.  If you want to send a TargetSubID, but not validate the returned SubID in the logon message, you must set this parameter to 0. The default value is 1.

manualSessionSwitch = n
This flag must be set to 1 if you are using fix version 4.2 or higher, and you want to use the ResetSession() method. The default value is 0. When this flag is 1, the log directories will have a 'version number' attached to the end of their name. Note: if this flag is set, the session will run until one side issues a ResetSession(). With this flag set to 0, a session is re-established at midnight local time  (or local 'virtual' time) - but further note: this only occurs when the fix gateway re-starts, hence, to cause a session reset when this flag is set to 0, you must close the fix gateway sometime before midnight, and re-start it after midnight.

CliSndBufSize n 
CliRecvBufSize n
These parameters specify the send and receive tcp/ip socket buffer size used within the client library when communicating with the FixGateway process, the default value is 0 which indicates the system-default is to be used. 

SrvInSndBufSize n 
SrvInRecvBufSize n 
These parameters specify the send and receive tcp/ip socket buffer size used within the FixGateway process when communicating with the client application, the default value is 0 which indicates the system-default is to be used. 

SrvOutSndBufSize n 
SrvOutRecvBufSize n 
These parameters specify the send and receive tcp/ip socket buffer size used within the FixGateway process when communicating with the remote Fix Engine, the default value is 0 which indicates the system-default is to be used. 

__useLCRP__ = n
See the implementation note at the end of this document. (The default value is 1)

String values can contain embedded spaces if they are surrounded by double or single quotes. Lines beginning with # are comments.


Client Library Properties File

fixgw.properties

This properties file must reside in the startup directory of your application that is using the aficlient.jar. This allows the client library to find the AFI Fix Engine. A suitable properties file is supplied with the installation and is located in the installation directory – normally you will just copy this and not change any of the entries. It contains the following entries which are all created during installation.

Home=C:\\Program Files\\Octatec\\AFI_J\\1.00
The installation directory, this will use single forward slashes if on UNIX, but if on Windows, it will use double backslashes.

Gateway=javaproc
Gateway process type. This entry tells the system to start the AFI Fix Engine in a new Java Virtual Machine, an alternative value is javathread, which will cause the Fix Engine to be started in a new thread in the current VM. (If you use javathread, you must ensure that afi.jar is on the classpath.)

Java=C:\\...\\bin\\java
The location of the java command

AFIsrv=C:\\...\\afi.jar
The location of the AFI Fix Engine classes

AFIcli=C:\\...\\JFixGW.jar
The location of additional Fix classes used by the Fix Engine


LogFiles and Journals

AFI's logfiles and journals

The location of these files is very important, and is controlled by the configuration file's LogDir entry.  These are created in a directory named YYYYMMDD_0  located in the Log Directory specified in the config file. Note: if  ManualSessionSwitch is set to 1 in the fix emgine properties file, the directories are named YYYYMMDD_N, where N is a version number that is incremented whenever a session is reset within any 24-hour period - if the reset takes place in a different 24 hour period, the YYYYMMDD part of the name will change and the N part will be 0.

One way of reseting the sequence number back to zero is simpley to delete these files.

The files created are as follows.

AFIserver.log
The general log file of the fix gateway, the LogLevel entry in the configuration file applies to this file only

FixJnl-TargetId.txt
The journal file - all outgoing messages are recorded here to enable resends of messages missed by the remote system.

FixRcv-TargetId.txt
The incoming journal - this is an optional file, and does not have any particular use.

SeqNo-TargetId.txt
A record of the current incoming and outgoing sequence numbers.

As already mentioned, you should endeavour to ensure that the fix gateway is closed down some time before midnight and started sometime after, so that the fix sequence numbers will restart at 0. It is the act of starting the fix gateway with an empty log directory that resets the sequence numbers to 0.
 

Client Library Log

The client library also creates a log file, FixGatewayClnt.log. The location of this log  is controlled by the fix engine properties file paramater cliLogDir. If this entry is not present, the logDir property is used instead. Once the base directory has been decided, a directory with the same name as the config file is created, and then a sub directory named YYYYMMDD_c is also created, finally the logfile is created in that directory. To summarize, the client library logfile is created as follows...

.../ConfigName/YYYYMMDD_c/FixGatewayClnt.log.

The sequence number of the last successfully processed fix message ( as defined by the FixSession.setComplete() method) is saved in .../ConfigName/YYYYMMDD_c/setcomplete.log

If the client application is using the output buffering mechanism, a buffer file is created in  .../ConfigName/buff.txt, this stores unflushed messages, when the buffer is flushed, it is renamed, .../ConfigName/buff.cmt.


FIXML Support

This package supports FIXML; it allows you to build ApplicationMessage FIXML sections using your favorite XML DOM implementation and pass these to the gateway, the gateway will add all the required FIXML headers around your ApplicationMessage.  To activate this functaionity, you need to set FIXML_addhdr andFIXML_addroot config parameters.

To make setting the XML payload of a standard FIX message slightly easier, the FixString.SetXmlPayload()method is provided.

You can find more details about FIXML support here.


The AfiClient Class library

This is an event-driven API and is extremely easy to use, it is the preferred method of accessing the AFI Fix Engine. It is built on top of  a low-level API which you can access, but are encouraged not to use.

Jar Files Needed: aficlient.jar, jfixgw.jar 

import com.octatec.aficlient.*;
import com.octatec.jfixgw.* ;
 

Abstract Class com.octatec.aficlient.FixHandler

You must derive your own class from the FixHandler class in order to process incoming FIX messages. The only method you really need to implement is onFixMsg(FixString s).

public void onPreCreate()
This method is called just before the fix session is created, it allows you to set low level options if you require them, mostly, you will not need to implement this method.

public void onOpenComplete()
This method is called just after a session is established with the remote FIX counterparty.

public void onLogon(FixString fixMsg)
If you have enabled notification of logon messages in the properties.file, [the default setting is to disable  logon notification] this method is called when the remote sends a logon message. You only need to implement this method if you are particularly interested in the remote’s logon message. This method will only be called if  the forwardLogon property is set to 1.

public void onHeartbeat (FixString fixMsg)
If you have enabled notification of heartbeat messages in the properties.file, [the default setting is to enable heartbeat notification] this method is called when the remote sends a heartbeat message. You only need to implement this method if you are particularly interested in heartbeat messages, (maybe you are using them as a timer?)

public void onRejection (FixString fixMsg)
If you have enabled notification of session protocol rejection messages in the properties.file, [the default setting is to disable  rejection notification]. This method is called when the remote sends a rejection message, the default behavioiur is for the fix engine to treat this as a ‘fatal’ error condition hence you will normally receive an onClose() notification not an onRejection(). You only need to implement this method is you have configured the fix engine to tolerate rejection messages sent from the remote side – something you will not normally want to do!

public void onRequestResend(FixString fixMsg)
If you have enabled confirmation of resend requests in the properties.file, [the default setting is to automatically fulfil all resend request] this method is called to ask permission to resend the specified message, if you return true the message is resent, if you return false a gap-fill is sent instead. You only need to implement this method if you do not want to automatically resend all requested messages

abstract public void onFixMsg(FixString)
This is the only method you really need to implement, it is called whenever an application-level fix message arrives. You should process the message as needed, a good first step is to put it in the database. You can use methods on the FixSession object (m_session)  to send response fix messages if required.

public void  onLogout()  DEPRECATED
This method is called when the fix session closes  normally. You do not need to implement this method, as the AfiApp.start() method will automatically return and no more messages will be received when the session closes. One reason you might want to implement this method is to call m_session.reopen(), if the reopen succeeds, the AfiApp.start() method will not return (at this juncture).
This method is now deprecated  and has been replaced by the following 2 methods.

public void onLocalLogout()
This is called is a local logout is issued within the application.

publi void onRemoteLogout(FixString msg)
This method is called when the remote logs out. The msg parameter will be null unless the forwardLogout property is set to 1.

public void  onError(int statuscode, boolean duringOpen)
This method is called when the fix session closes due to an error. Again, you do not need to implement this method, as the AfiApp.start() method will automatically return and no more messages will be received when the session closes. Again, one reason you might want to implement this method is to call m_session.reopen(), if the reopen succeeds, the AfiApp.start() method will not return (at this juncture). The duringOpen parameter will be true if the error occurred  during the attempt to open the session.

public void onClosed()
This method is called once the session is completely closed, for either of  the above 2 reasons or if you called m_session.logout(). (Note: It is too late to call m_session.reopen() from here.) NB - for every session you will either get an onError() or an onLogout(), this will cause the open session to close automatically, so you will then get an onClosed() event. If you call m_session.logout() you will get still get onLogout( ) followed by an onClosed(). If an error occurs during the attempt to open a session you will still get an onError() event but with duringOpen set to true, you will immediately get an onClosed() event to maintain consistent ordering and delivery of events.

onThreadMessageSent(String type, FixString sfix, int result)
This method will only be called if you used the AfiThreadedApp  object when creating your application: In this case your Fix session will be in a worker thread. If you call  AfiThreadedApp. sendThreadFixMsg(type, sfix), this method will be called immediately after the worker thread actually sends the message (. If result is not 0, it indicates an error, and to preserve consistency in the API, onError() will also be called immediately after this method. (Note: type and sfix could be null if a serious error occurs.) You don’t need to do anything in this method, but it may be important for you to know that the fix-message failed to be sent, remember the User Interface thread that used sendThreadFixMsg(type, sfix) will not know for sure that the message has been successfully sent to the remote fix engine - the return value of sendThreadFixMsg(type, sfix) only indicates that the message has been successfully sent on its way to the worker thread.
(NOTE: the actual sending of the message in response to AfiThreadedApp. sendThreadFixMsg(type, sfix) is performed  automatically by the frame-work, you don’t need to worry about that, and then once sent, ths method is called to inform you of the fact.)

public void onThreadCmd(short cmd, String text)
This method will only be called if you used the AfiThreadedApp  object when creating your application. In this case your Fix session will be in a worker thread, and the GUI or foreground thread can use AfiThreadedApp.sendThreadCmd() to send the Fix Worker Thread messages. NB: the text parameter may be null.

public void onUserError(Throwable t)
This method is called if an Exception (Throwable) is thrown from any of the above methods. For example, if you access a null reference or perform some other programing error in one of the above methods, unless you catch the exception yourself, this method will be called.

protected FixSession  m_session
This member contains the current FixSession object and is guaranteed never to be null. Your FixHandler class can call methods on this object, typically to send Fix messages or close the session.
 
 

Class com.octatec.aficlient.FixSession

This class is created automatically and is made available to your application via the FixHandler.m_session member.

public void sendMsg(String type, FixString fixMsg) throws AfiException;
Send a Fix message of the specified type. If you are in a loop sending fix messages, your application will not be able to receive any incoming messages until the loop completes.

Note: the correct thing to do when catching an AfiException thrown by any method is, after recording whatever information you want, call m_session.handleException(x), and then return immediately. Doing this allows the session to tidy up correctly and will also give rise to you handler’s onError() method being called.

public void sendMsgEx(String type, FixString fixMsg) throws AfiException;
Send a Fix message of the specified type. After the messages has been sent, the system will check for any incoming messages, and if there are any, they will be dispatched by the system. So your Fixhandler’s onFixMessage() or other methods may be called before this method returns. If you are in a loop sending fix messages, your application will still receive incoming messages while the loop is active.

public void logout()
Send a logout message and close the session.

public boolean reopen() 
You can call this method to attempt to re-open a closed session, typically, you will call it from your FixHandler’s onClose() method. The reopen() call will wait until a connection has been made or until an error occurs.

public void setComplete()
Use this method to indicate to the system that all messages received to-date have been fully processed (or saved in your database for latter processing). If this has not been called, and the application crashes (or exits in some other way), any messages received (since the last call to setComplete ) will be re-requested automatically when the application is next started. If you don’t want to have to call setComplete(), you can use the following method.

public boolean  enableAutoSetComplete()
If you are going to call this method, you MUST do so before the fix session is established, i.e. from you’re your FixHandler’s onPreCreate() method. If you call this method, all messages received are automatically marked as ‘fully’ processed, and there is no need to call setComplete().

public void beginBufferedOutput() throws AfiException;
public void abortBufferedOutput() throws AfiException;
public void flushBufferedOutput() throws AfiException;
If you call beginBufferdOutput(), all subsequent calls to sendMsg() or sendMsgEx() will merely add the message to a persistent buffer. The messages will not be sent until flushBufferdOutput() is called. If  abortBufferdOutput() is called the buffer is discarded. If you use this facility, and the application exits before you flush the buffer, the buffer is automatically flushed the next time your application runs. if you don't want to flush the buffer on application start-up, you can call, abortBufferdOutput() from your FixHandler’s onPreCreate() method, it is always safe to do this, even if there is no buffer to abort, (no exception will be thrown).

public void handleException(AfiException x)
This method should be called whenever you catch an AfiException; you will almost certainly be in a FixHandler method at the time - you should return immediately after calling this method. Calling handleException() allows the session to tidy up correctly and will also give rise to you FixHanler’s onError() method being called.

public FixClient getLowLevelApi();
You can call this method to access the ‘low-level api’, mostly you should not need to access the low-level api at all, but if you have special requirements, you can do this. One reason to use the low-level API is to send script file, the afisrv test program uses this facility,
 

Class com.octatec.aficlient.AfiApp

You should create one of these objects to run your application

public AfiApp(String propertiesFile);
Pass a properties file that defines the fix session connection parameters such as IPAddress and port.

public int  start(FixHandler handler);
Once you have created the AfiApp object, call this method to actually start the fix session, pass in your FixHandler-derriver object to this method.
 
 

Class com.octatec.aficlient.AfiThreadedApp

You can create an instance of this object instead of an AfiApp object if you want  your Fix session to run in a worker thread, perhaps your foreground thread will be presenting a GUI to a user. Internally, an AfiApp instance is created in its own thread. You could do this yourself if you wished, but the advantage of using the AfiThreadedApp  object is that you can use the sendThreadCmd() methods from te GUI thread to send ‘internal’ messages to your FixHandler class in the worker thread, in which case your FixHandler's onThreadCmd(short cmd, String text) method will be called

AfiThreadedApp(String propertiesFile)
Pass a properties file that defines the fix session connection parameters such as IPAddress and port.

public boolean startThread(FixHandler handler);
Create a new worker thread to run your fix session. The worker thread will automatically initiate the fix connection when this method is called.
This method will not return until a connection  has been made or an error has occurred.

public void startThreadNoWait(FixHandler handler);
Create a new worker thread to run your fix session. The worker thread will automatically initiate the fix connection when this method is called. This method will return immediately.

public boolean closeThread();
This will cause the worker thread to send a logout and close the session, if this method is called, any call to FixSession.reopen() will automatically fail.

public boolean sendThreadFixMsg(String type, FixString sfix)
You can call this method from the User Interface thread to cause the worker thread to send the specified fix message.  Your fix handlers onThreadMessageSent(type, sfix, result) will be called after the message has been sent in the worker thread, if result indicates an error, your fix handlers onError() will also be called. Of course, you don’t have to use this method to send fix messages – if your message can be generated entirely from the worker thread, e.g. in response to an incoming message, you can just use the m_session.sendMsg()  method from you fix handler. Note: this method will return false if you try and send an empty fix message.

public boolean sendThreadCmd(short cmd);
Send an arbitrary notification to the Fix session thread. The cmd parameter should be above 100, other than that, it can be any value you choose, and you can interpret it in any way you choose in your FixHandler’s  onThreadCmd(short cmd, String text) method, note the text parameter will be null.

public boolean sendThreadCmd(short cmd, String text);
This method allows you to also send an arbitrary notification and a text string to the worker thread. The cmd parameter should be above 100.

int getLastStatusCode();
You can use this method to ‘poll’ the status of the worker thread, however, you should probably implement some sort of notification send from the worker to the GUI thread if an important event occurs that the GUI needs to know about, e.g. using something like EventQueue.invokeLater()

The following class is actually found in the low-level API, but is used extensively by this class library, and encapsulates a fix message…
 
 

Class com.octatec.jfixgw.FixString

This class provides the functionality for building fix messages and accessing all the fields of the message. The class FixConst provides you with a list of current Fix Fields and Message Types. You can, however, use any value as a Fix Field ID, and any value for a Fix Field Type.

new FixString()
new FixString(String s)
Construct a fix message string, either empty, or from a string containing fix fields. Note: their is no validation of the string passed into the constructor.

void Set(String s)
Set the contents of the fix string to the specified value. Note: their is no validation of the string passed in.

String GetMsgType()
Return the type of a fix message. This will be one of the FIX_MSG_* values defined in FixConst

bool GetField(int tag, OutputString value)
bool GetField(int tag, OutputInt    value)
void AddField(int tag, int    value)
void AddField(int tag, String value)
void UpdateOrAddField(int tag, int value)
void UpdateOrAddField(int tag, String value)
bool RemoveField(int tag)
The above set of methods are likely to be the most useful. In all cases name is just the numerical value of the field (tag). It is most likely to be one of the FIX_FLD_* values in FixConst but could be any value. The methods treat the contents of fields as either strings or integers, if the field has a different type, e.g. date/time or floating point, you must extract it as a string and convert it.

String GetField(int tag)
A slightly more convenient method, if the field isn’t present, an empty string is returned.

void SetXmlPayload(String xmlText)
This method discards any tags you ay have already set, just sets the XmlDataLen and XmlData tags based on the xmlText parameter. You probably shoudn’t add any more tags to the message after this one, although you can if you want. You can then send the message using any ‘type’ you wish, it is up to the receiving end to be prepared to decode your XML payload if you use a traditional FIX-MSG-TYPE, or to understand any other type filed you may choose to use, such as “XML” or “FIXML”. It is up to you to serialize your XML into a flat sting before passing it to this method, this might be as easy as reading it into a buffer from an xml file. Note: if you are sending FIXML, there are a couple of config parameters to help you, and a further discussion here. 

String GetXmlPayload()
This method is realy the equivalent of calling GetField(FIX_FLD_XmlData) If there is no XML payload present, null is returned. 

void InitEnum()
boolean EnumNextField(OutputInt name, OutputString value);
These 2 methods enable the enumeration of all fields in a fix string. You should call InitEnum(), once then repeatedly call EnumNextField() until it returns false.

void EmptyString()
Clear the contents of a fix string

String GetString()
Get a reference to the actual string

static Calendar GetCurretTime() // implies gmtOffeset = Config.V_LOCAL_TIME
static Calendar GetCurretTime(short gmtOffeset) 
This is a convenience method to get the current time taking into account the GMT offset (virtual timezone) present in the Fix Gateway process. If the first version of the method is used, any GMT offset is ignored, and the current local time is returned.

static String FormatDate(Calendar cal) // implies format = FixString.FMT_LONG_MS
static String FormatTime(Calendar cal, int format);
Convert the date in cal into a fix format string. If cal is null, then  the current date/time is used. If format=FixString.FMT_LONG_MS, the output is in the form YYYYMMDD-HH:MM:SS.sss, if format=FixString.FMT_LONG, the output is in the form YYYYMMDD-HH:MM:SS and if format=FMT_SHORThe output is in the form YYYYMMDD

static Calendar ParseDate(String s); // YYYYMMDD  or   YYYYMMDD-HH:MM:SS.sss
Return a Calendar object that representd the date/time in the input fix date/time string.
 
 

Class com.octatec.jfixgw.OutputString

This is a class with a single public m_value String member. It is used to return output string values via parameters from various methods.

new OutpuString(String value);
new OutpuString();

boolean equals(Object o);
boolean equals(OutputString s);
boolean equals(String s);
These 2 methods compare the characters in the strings and not the object references.
 
 

Class com.octatec.jfixgw.OutputInt

This is a class with a single public m_value int member. It is used to return output int values via parameters from various methods.

new OutputInt(int value);
new OutputInt();
 
 

Class com.octatec.jfixgw.OutputShort

This is a class with a single public m_value short member. It is used to return output short values via parameters from various methods.

new OutputShort(short value);
new OutputShort();
 
 

Class com.octatec.jfixgw.OutputBool

This is a class with a single public m_value boolean member. It is used to return output boolean values via parameters from various methods.

new OutputBool(boolean value);
new OutputBool();
 
 

Class com.octatec.jfixgw.FixConst

This class defines all the Fix Message Types and most of the Fix Fields (tags) that can be used in the various messages. The FIX_MSG_ constants can be used as arguments to the FixSession.SendMsg() method, while the FIX_FLD_ constants can be used as the ‘name’ parameter to various methods in the FixString class.

  public  static final String FIX_Delimiter = "\001";

 public  static final String FIX_MSG_Heartbeat     ="0";
 public  static final String FIX_MSG_Test_Request    ="1";
 public  static final String FIX_MSG_Resend_Request    ="2";
 public  static final String FIX_MSG_Reject      ="3";
 public  static final String FIX_MSG_Sequence_Reset    ="4";
 public  static final String FIX_MSG_Logout      ="5";
 public  static final String FIX_MSG_Indication_of_Interest  ="6";
 public  static final String FIX_MSG_Advertisement    ="7";
 public  static final String FIX_MSG_Execution_Report   ="8";
 public  static final String FIX_MSG_Order_Cancel_Reject   ="9";
 public  static final String FIX_MSG_Logon      ="A";
 public  static final String FIX_MSG_News      ="B";
 public  static final String FIX_MSG_Email      ="C";
 public  static final String FIX_MSG_Order_Single    ="D";
 public  static final String FIX_MSG_Order_List     ="E";
 public  static final String FIX_MSG_Order_Cancel_Request  ="F";
 public  static final String FIX_MSG_Order_Cancel_Replace_Request="G";
 public  static final String FIX_MSG_Order_Status_Request  ="H";
 public  static final String FIX_MSG_Allocation     ="J";
 public  static final String FIX_MSG_List_Cancel_Request   ="K";
 public  static final String FIX_MSG_List_Execute    ="L";
 public  static final String FIX_MSG_List_Status_Request   ="M";
 public  static final String FIX_MSG_List_Status     ="N";
 public  static final String FIX_MSG_Allocation_ACK    ="P";
 public  static final String FIX_MSG_Dont_Know_Trade    ="Q";
 public  static final String FIX_MSG_Quote_Request    ="R";
 public  static final String FIX_MSG_Quote      ="S";
 public  static final String FIX_MSG_Settlement_Instructions  ="T";
 public  static final String FIX_MSG_Market_Data_Request   ="V";
 public  static final String FIX_MSG_Market_Data_Full_Refresh ="W";
 public  static final String FIX_MSG_Market_Data_Incremental_Refresh ="X";
 public  static final String FIX_MSG_Market_Data_Request_Reject  ="Y";
 public  static final String FIX_MSG_Quote_Cancel     ="Z";
 public  static final String FIX_MSG_Quote_Status_Request   ="a";
 public  static final String FIX_MSG_Quote_Acknowledgement   ="b";
 public  static final String FIX_MSG_Security_Definition_Request  ="c";
 public  static final String FIX_MSG_Security_Definition   ="d";
 public  static final String FIX_MSG_Security_Status_Request   ="e";
 public  static final String FIX_MSG_Security_Status     ="f";
 public  static final String FIX_MSG_Trading_Session_Status_Request ="g";
 public  static final String FIX_MSG_Trading_Session_Status   ="h";
 public  static final String FIX_MSG_Mass_Quote      ="i";
 public  static final String FIX_MSG_Business_Message_Reject   ="j";
 public  static final String FIX_MSG_Bid_Request      ="k";
 public  static final String FIX_MSG_Bid_Response     ="l";
 public  static final String FIX_MSG_List_Strike_Price    ="m";

 public static final String FIX_MSG_XML  = "XML";
 public  static final String FIX_MSG_FIXML = "FIXML";
   // you can use either of these or any other localy agreed
   // message type to indicate the FIX MESSAGE actually
   // contains FIXML or aome other XML payload, these are
   // just included as a sugestion

 public  static final int FIX_FLD_Account   =1;
 public  static final int FIX_FLD_AdvId    =2;
 public  static final int FIX_FLD_AdvRefID   =3;
 public  static final int FIX_FLD_AdvSide   =4;
 public  static final int FIX_FLD_AdvTransType  =5;
 public  static final int FIX_FLD_AvgPx    =6;
 public  static final int FIX_FLD_BeginSeqNo   =7;
 public  static final int FIX_FLD_BeginString  =8;
 public  static final int FIX_FLD_BodyLength   =9;
 public  static final int FIX_FLD_CheckSum   =10;
 public  static final int FIX_FLD_ClOrdID   =11;
 public  static final int FIX_FLD_Commission   =12;
 public  static final int FIX_FLD_CommType   =13;
 public  static final int FIX_FLD_CumQty    =14;
 public  static final int FIX_FLD_Currency   =15;
 public  static final int FIX_FLD_EndSeqNo   =16;
 public  static final int FIX_FLD_ExecID    =17;
 public  static final int FIX_FLD_ExecInst   =18;
 public  static final int FIX_FLD_ExecRefID   =19;
 public  static final int FIX_FLD_ExecTransType  =20;
 public  static final int FIX_FLD_HandlInst   =21;
 public  static final int FIX_FLD_IDSource   =22;
 public  static final int FIX_FLD_IOIid    =23;
 public  static final int FIX_FLD_IOIOthSvc   =24;
 public  static final int FIX_FLD_IOIQltyInd   =25;
 public  static final int FIX_FLD_IOIRefID   =26;
 public  static final int FIX_FLD_IOIShares   =27;
 public  static final int FIX_FLD_IOITransType  =28;
 public  static final int FIX_FLD_LastCapacity  =29;
 public  static final int FIX_FLD_LastMkt   =30;
 public  static final int FIX_FLD_LastPx    =31;
 public  static final int FIX_FLD_LastShares   =32;
 public  static final int FIX_FLD_LinesOfText  =33;
 public  static final int FIX_FLD_MsgSeqNum   =34;
 public  static final int FIX_FLD_MsgType   =35;
 public  static final int FIX_FLD_NewSeqNo   =36;
 public  static final int FIX_FLD_OrderID   =37;
 public  static final int FIX_FLD_OrderQty   =38;
 public  static final int FIX_FLD_OrdStatus   =39;
 public  static final int FIX_FLD_OrdType   =40;
 public  static final int FIX_FLD_OrigClOrdID  =41;
 public  static final int FIX_FLD_OrigTime   =42;
 public  static final int FIX_FLD_PossDupFlag  =43;
 public  static final int FIX_FLD_Price    =44;
 public  static final int FIX_FLD_RefSeqNum   =45;
 public  static final int FIX_FLD_RelatdSym   =46;
 public  static final int FIX_FLD_Rule80A   =47;
 public  static final int FIX_FLD_SecurityID   =48;
 public  static final int FIX_FLD_SenderCompID  =49;
 public  static final int FIX_FLD_SenderSubID  =50;
 public  static final int FIX_FLD_SendingDate  =51;
 public  static final int FIX_FLD_SendingTime  =52;
 public  static final int FIX_FLD_Shares    =53;
 public  static final int FIX_FLD_Side    =54;
 public  static final int FIX_FLD_Symbol    =55;
 public  static final int FIX_FLD_TargetCompID  =56;
 public  static final int FIX_FLD_TargetSubID  =57;
 public  static final int FIX_FLD_Text    =58;
 public  static final int FIX_FLD_TimeInForce  =59;
 public  static final int FIX_FLD_TransactTime  =60;
 public  static final int FIX_FLD_Urgency   =61;
 public  static final int FIX_FLD_ValidUntilTime  =62;
 public  static final int FIX_FLD_SettlmntTyp  =63;
 public  static final int FIX_FLD_FutSettDate  =64;
 public  static final int FIX_FLD_SymbolSfx   =65;
 public  static final int FIX_FLD_ListID    =66;
 public  static final int FIX_FLD_ListSeqNo   =67;
 public  static final int FIX_FLD_TotNoOrders  =68;
 public  static final int FIX_FLD_ListNoOrds   =68;
 public  static final int FIX_FLD_ListExecInst  =69;
 public  static final int FIX_FLD_AllocID   =70;
 public  static final int FIX_FLD_AllocTransType  =71;
 public  static final int FIX_FLD_RefAllocID   =72;
 public  static final int FIX_FLD_NoOrders   =73;
 public  static final int FIX_FLD_AvgPrxPrecision =74;
 public  static final int FIX_FLD_TradeDate   =75;
 public  static final int FIX_FLD_ExecBroker   =76;
 public  static final int FIX_FLD_OpenClose  =77;
 public  static final int FIX_FLD_NoAllocs   =78;
 public  static final int FIX_FLD_AllocAccount  =79;
 public  static final int FIX_FLD_AllocShares  =80;
 public  static final int FIX_FLD_ProcessCode  =81;
 public  static final int FIX_FLD_NoRpts    =82;
 public  static final int FIX_FLD_RptSeq    =83;
 public  static final int FIX_FLD_CxlQty    =84;
 public  static final int FIX_FLD_NoDlvyInst   =85;
 public  static final int FIX_FLD_DlvyInst   =86;
 public  static final int FIX_FLD_AllocStatus  =87;
 public  static final int FIX_FLD_AllocRejCode  =88;
 public  static final int FIX_FLD_Signature   =89;
 public  static final int FIX_FLD_SecureDataLen  =90;
 public  static final int FIX_FLD_SecureData   =91;
 public  static final int FIX_FLD_BrokerOfCredit  =92;
 public  static final int FIX_FLD_SignatureLength =93;
 public  static final int FIX_FLD_EmailType   =94;
 public  static final int FIX_FLD_RawDataLength  =95;
 public  static final int FIX_FLD_RawData   =96;
 public  static final int FIX_FLD_PossResend  =97;
 public  static final int FIX_FLD_EncryptMethod  =98;
 public  static final int FIX_FLD_StopPx    =99;
 public  static final int FIX_FLD_ExDestination  =100;
 public  static final int FIX_FLD___Not_Defined  =101;
 public  static final int FIX_FLD_CxlRejReason  =102;
 public  static final int FIX_FLD_OrdRejReason  =103;
 public  static final int FIX_FLD_IOIQualifier  =104;
 public  static final int FIX_FLD_WaveNo    =105;
 public  static final int FIX_FLD_Issuer    =106;
 public  static final int FIX_FLD_SecurityDesc  =107;
 public  static final int FIX_FLD_HeartBtInt   =108;
 public  static final int FIX_FLD_ClientID   =109;
 public  static final int FIX_FLD_MinQty    =110;
 public  static final int FIX_FLD_MaxFloor   =111;
 public  static final int FIX_FLD_TestReqID   =112;
 public  static final int FIX_FLD_ReportToExch  =113;
 public  static final int FIX_FLD_LocateReqd   =114;
 public  static final int FIX_FLD_OnBehalfOfCompID =115;
 public  static final int FIX_FLD_OnBehalfOfSubID =116;
 public  static final int FIX_FLD_QuoteID   =117;
 public  static final int FIX_FLD_NetMoney   =118;
 public  static final int FIX_FLD_SettlCurrAmt  =119;
 public  static final int FIX_FLD_SettlCurrency  =120;
 public  static final int FIX_FLD_ForexReq   =121;
 public  static final int FIX_FLD_OrigSendingTime =122;
 public  static final int FIX_FLD_GapFillFlag  =123;
 public  static final int FIX_FLD_NoExecs   =124;
 public  static final int FIX_FLD_CxlType   =125;
 public  static final int FIX_FLD_ExpireTime   =126;
 public  static final int FIX_FLD_DKReason   =127;
 public  static final int FIX_FLD_DeliverToCompID =128;
 public  static final int FIX_FLD_DeliverToSubID  =129;
 public  static final int FIX_FLD_IOINaturalFlag  =130;
 public  static final int FIX_FLD_QuoteReqID   =131;
 public  static final int FIX_FLD_BidPx    =132;
 public  static final int FIX_FLD_OfferPx   =133;
 public  static final int FIX_FLD_BidSize   =134;
 public  static final int FIX_FLD_OfferSize   =135;
 public  static final int FIX_FLD_NoMiscFees   =136;
 public  static final int FIX_FLD_MiscFeeAmt   =137;
 public  static final int FIX_FLD_MiscFeeCurr  =138;
 public  static final int FIX_FLD_MiscFeeType  =139;
 public  static final int FIX_FLD_PrevClosePx  =140;
 public  static final int FIX_FLD_ResetSeqNumFlag =141;
 public  static final int FIX_FLD_SenderLocationID =142;
 public  static final int FIX_FLD_TargetLocationID =143;
 public  static final int FIX_FLD_OnBehalfOfLocationID =144;
 public  static final int FIX_FLD_DeliverToLocationID =145;
 public  static final int FIX_FLD_NoRelatedSym   =146;
 public  static final int FIX_FLD_Subject    =147;
 public  static final int FIX_FLD_Headline    =148;
 public  static final int FIX_FLD_URLLink    =149;
 public  static final int FIX_FLD_ExecType    =150;
 public  static final int FIX_FLD_LeavesQty    =151;
 public  static final int FIX_FLD_CashOrderQty   =152;
 public  static final int FIX_FLD_AllocAvgPx    =153;
 public  static final int FIX_FLD_AllocNetMoney   =154;
 public  static final int FIX_FLD_SettlCurrFxRate  =155;
 public  static final int FIX_FLD_SettlCurrFxRateCalc =156;
 public  static final int FIX_FLD_NumDaysInterest  =157;
 public  static final int FIX_FLD_AccruedInterestRate =158;
 public  static final int FIX_FLD_AccruedInterestAmt  =159;
 public  static final int FIX_FLD_SettlInstMode   =160;
 public  static final int FIX_FLD_AllocText    =161;
 public  static final int FIX_FLD_SettlInstID   =162;
 public  static final int FIX_FLD_SettlInstTransType  =163;
 public  static final int FIX_FLD_EmailThreadID   =164;
 public  static final int FIX_FLD_SettlInstSource  =165;
 public  static final int FIX_FLD_SettlLocation   =166;
 public  static final int FIX_FLD_SecurityType   =167;
 public  static final int FIX_FLD_EffectiveTime   =168;
 public  static final int FIX_FLD_StandInstDbType  =169;
 public  static final int FIX_FLD_StandInstDbName  =170;
 public  static final int FIX_FLD_StandInstDbID   =171;
 public  static final int FIX_FLD_SettlDeliveryType  =172;
 public  static final int FIX_FLD_SettlDepositoryCode =173;
 public  static final int FIX_FLD_SettlBrkrCode   =174;
 public  static final int FIX_FLD_SettlInstCode   =175;
 public  static final int FIX_FLD_SecuritySettlAgentName =176;
 public  static final int FIX_FLD_SecuritySettlAgentCode =177;
 public  static final int FIX_FLD_SecuritySettlAgentAcctNum  =178;
 public  static final int FIX_FLD_SecuritySettlAgentAcctName  =179;
 public  static final int FIX_FLD_SecuritySettlAgentContactName =180;
 public  static final int FIX_FLD_SecuritySettlAgentContactPhone =181;
 public  static final int FIX_FLD_CashSettlAgentName    =182;
 public  static final int FIX_FLD_CashSettlAgentCode    =183;
 public  static final int FIX_FLD_CashSettlAgentAcctNum   =184;
 public  static final int FIX_FLD_CashSettlAgentAcctName   =185;
 public  static final int FIX_FLD_CashSettlAgentContactName  =186;
 public  static final int FIX_FLD_CashSettlAgentContactPhone  =187;
 public  static final int FIX_FLD_BidSpotRate     =188;
 public  static final int FIX_FLD_BidForwardPoints    =189;
 public  static final int FIX_FLD_OfferSpotRate     =190;
 public  static final int FIX_FLD_OfferForwardPoints    =191;
 public  static final int FIX_FLD_OrderQty2      =192;
 public  static final int FIX_FLD_FutSettDate2     =193;
 public  static final int FIX_FLD_LastSpotRate     =194;
 public  static final int FIX_FLD_LastForwardPoints    =195;
 public  static final int FIX_FLD_AllocLinkID     =196;
 public  static final int FIX_FLD_AllocLinkType   =197;
 public  static final int FIX_FLD_SecondaryOrderID  =198;
 public  static final int FIX_FLD_NoIOIQualifiers  =199;
 public  static final int FIX_FLD_MaturityMonthYear  =200;
 public  static final int FIX_FLD_PutOrCall    =201;
 public  static final int FIX_FLD_StrikePrice   =202;
 public  static final int FIX_FLD_CoveredOrUncovered  =203;
 public  static final int FIX_FLD_CustomerOrFirm   =204;
 public  static final int FIX_FLD_MaturityDay   =205;
 public  static final int FIX_FLD_OptAttribute   =206;
 public  static final int FIX_FLD_SecurityExchange  =207;
 public  static final int FIX_FLD_NotifyBrokerOfCredit =208;
 public  static final int FIX_FLD_AllocHandlInst   =209;
 public  static final int FIX_FLD_MaxShow    =210;
 public  static final int FIX_FLD_PegDifference   =211;
 public  static final int FIX_FLD_XmlDataLen    =212;
 public  static final int FIX_FLD_XmlData    =213;
 public  static final int FIX_FLD_SettlInstRefID   =214;
 public  static final int FIX_FLD_NoRoutingIDs   =215;
 public  static final int FIX_FLD_RoutingType   =216;
 public  static final int FIX_FLD_RoutingID    =217;
 public  static final int FIX_FLD_SpreadToBenchmark  =218;
 public  static final int FIX_FLD_Benchmark    =219;
 public  static final int FIX_FLD_CouponRate    =223;
 public  static final int FIX_FLD_ContractMultiplier  =231;
 public  static final int FIX_FLD_MDReqID    =262;
 public  static final int FIX_FLD_SubscriptionRequestType=263;
 public  static final int FIX_FLD_MarketDepth   =264;
 public  static final int FIX_FLD_MDUpdateType   =265;
 public  static final int FIX_FLD_AggregatedBook   =266;
 public  static final int FIX_FLD_NoMDEntryTypes   =267;
 public  static final int FIX_FLD_NoMDEntries   =268;
 public  static final int FIX_FLD_MDEntryType  =269;
 public  static final int FIX_FLD_MDEntryPx    =270;
 public  static final int FIX_FLD_MDEntrySize   =271;
 public  static final int FIX_FLD_MDEntryDate   =272;
 public  static final int FIX_FLD_MDEntryTime   =273;
 public  static final int FIX_FLD_TickDirection   =274;
 public  static final int FIX_FLD_MDMkt     =275;
 public  static final int FIX_FLD_QuoteCondition   =276;
 public  static final int FIX_FLD_TradeCondition   =277;
 public  static final int FIX_FLD_MDEntryID    =278;
 public  static final int FIX_FLD_MDUpdateAction   =279;
 public  static final int FIX_FLD_MDEntryRefID   =280;
 public  static final int FIX_FLD_MDReqRejReason   =281;
 public  static final int FIX_FLD_MDEntryOriginator  =282;
 public  static final int FIX_FLD_LocationID   =283;
 public  static final int FIX_FLD_DeskID     =284;
 public  static final int FIX_FLD_DeleteReason   =285;
 public  static final int FIX_FLD_OpenCloseSettleFlag =286;
 public  static final int FIX_FLD_SellerDays    =287;
 public  static final int FIX_FLD_MDEntryBuyer   =288;
 public  static final int FIX_FLD_MDEntrySeller   =289;
 public  static final int FIX_FLD_MDEntryPositionNo  =290;
 public  static final int FIX_FLD_FinancialStatus =291;
 public  static final int FIX_FLD_CorporateAction  =292;
 public  static final int FIX_FLD_DefBidSize    =293;
 public  static final int FIX_FLD_DefOfferSize   =294;
 public  static final int FIX_FLD_NoQuoteEntries   =295;
 public  static final int FIX_FLD_NoQuoteSets   =296;
 public  static final int FIX_FLD_QuoteAckStatus   =297;
 public  static final int FIX_FLD_QuoteCancelType  =298;
 public  static final int FIX_FLD_QuoteEntryID   =299;
 public  static final int FIX_FLD_QuoteRejectReason  =300;
 public  static final int FIX_FLD_QuoteResponseLevel  =301;
 public  static final int FIX_FLD_QuoteSetID    =302;
 public  static final int FIX_FLD_QuoteRequestType  =303;
 public  static final int FIX_FLD_TotQuoteEntries  =304;
 public  static final int FIX_FLD_UnderlyingIDSource  =305;
 public  static final int FIX_FLD_UnderlyingIssuer  =306;
 public  static final int FIX_FLD_UnderlyingSecurityDesc =307;
 public  static final int FIX_FLD_UnderlyingSecurityExchange =308;
 public  static final int FIX_FLD_UnderlyingSecurityID  =309;
 public  static final int FIX_FLD_UnderlyingSecurityType  =310;
 public  static final int FIX_FLD_UnderlyingSymbol   =311;
 public  static final int FIX_FLD_UnderlyingSymbolSfx  =312;
 public  static final int FIX_FLD_UnderlyingMaturityMonthYear=313;
 public  static final int FIX_FLD_UnderlyingMaturityDay  =314;
 public  static final int FIX_FLD_UnderlyingPutOrCall  =315;
 public  static final int FIX_FLD_UnderlyingStrikePrice  =316;
 public  static final int FIX_FLD_UnderlyingOptAttribute  =317;
 public  static final int FIX_FLD_Underlying     =318;
 public  static final int FIX_FLD_RatioQty     =319;
 public  static final int FIX_FLD_SecurityReqID    =320;
 public  static final int FIX_FLD_SecurityRequestType  =321;
 public  static final int FIX_FLD_SecurityResponseID   =322;
 public  static final int FIX_FLD_SecurityResponseType  =323;
 public  static final int FIX_FLD_SecurityStatusReqID  =324;
 public  static final int FIX_FLD_UnsolicitedIndicator  =325;
 public  static final int FIX_FLD_SecurityTradingStatus  =326;
 public  static final int FIX_FLD_HaltReason     =327;
 public  static final int FIX_FLD_InViewOfCommon    =328;
 public  static final int FIX_FLD_DueToRelated    =329;
 public  static final int FIX_FLD_BuyVolume      =330;
 public  static final int FIX_FLD_SellVolume     =331;
 public  static final int FIX_FLD_HighPx       =332;
 public  static final int FIX_FLD_LowPx       =333;
 public  static final int FIX_FLD_Adjustment     =334;
 public  static final int FIX_FLD_TradSesReqID    =335;
 public  static final int FIX_FLD_TradingSessionID   =336;
 public  static final int FIX_FLD_ContraTrader    =337;
 public  static final int FIX_FLD_TradSesMethod    =338;
 public  static final int FIX_FLD_TradSesMode    =339;
 public  static final int FIX_FLD_TradSesStatus    =340;
 public  static final int FIX_FLD_TradSesStartTime   =341;
 public  static final int FIX_FLD_TradSesOpenTime   =342;
 public  static final int FIX_FLD_TradSesPreCloseTime  =343;
 public  static final int FIX_FLD_TradSesCloseTime   =344;
 public  static final int FIX_FLD_TradSesEndTime    =345;
 public  static final int FIX_FLD_NumberOfOrders    =346;
 public  static final int FIX_FLD_MessageEncoding   =347;
 public  static final int FIX_FLD_EncodedIssuerLen   =348;
 public  static final int FIX_FLD_EncodedIssuer    =349;
 public  static final int FIX_FLD_EncodedSecurityDescLen  =350;
 public  static final int FIX_FLD_EncodedSecurityDesc  =351;
 public  static final int FIX_FLD_EncodedListExecInstLen  =352;
 public  static final int FIX_FLD_EncodedListExecInst  =353;
 public  static final int FIX_FLD_EncodedTextLen    =354;
 public  static final int FIX_FLD_EncodedText    =355;
 public  static final int FIX_FLD_EncodedSubjectLen   =356;
 public  static final int FIX_FLD_EncodedSubject    =357;
 public  static final int FIX_FLD_EncodedHeadlineLen   =358;
 public  static final int FIX_FLD_EncodedHeadline   =359;
 public  static final int FIX_FLD_EncodedAllocTextLen  =360;
 public  static final int FIX_FLD_EncodedAllocText   =361;
 public  static final int FIX_FLD_EncodedUnderlyingIssuerLen =362;
 public  static final int FIX_FLD_EncodedUnderlyingIssuer =363;
 public  static final int FIX_FLD_EncodedUnderlyingSecurityDescLen =364;
 public  static final int FIX_FLD_EncodedUnderlyingSecurityDesc  =365;
 public  static final int FIX_FLD_AllocPrice     =366;
 public  static final int FIX_FLD_QuoteSetValidUntilTime  =367;
 public  static final int FIX_FLD_QuoteEntryRejectReason  =368;
 public  static final int FIX_FLD_LastMsgSeqNumProcessed  =369;
 public  static final int FIX_FLD_OnBehalfOfSendingTime  =370;
 public  static final int FIX_FLD_RefTagID     =371;
 public  static final int FIX_FLD_RefMsgType     =372;
 public  static final int FIX_FLD_SessionRejectReason  =373;
 public  static final int FIX_FLD_BidRequestTransType  =374;
 public  static final int FIX_FLD_ContraBroker    =375;
 public  static final int FIX_FLD_ComplianceID    =376;
 public  static final int FIX_FLD_SolicitedFlag    =377;
 public  static final int FIX_FLD_ExecRestatementReason  =378;
 public  static final int FIX_FLD_BusinessRejectRefID  =379;
 public  static final int FIX_FLD_BusinessRejectReason  =380;
 public  static final int FIX_FLD_GrossTradeAmt    =381;
 public  static final int FIX_FLD_NoContraBrokers  =382;
 public  static final int FIX_FLD_MaxMessageSize    =383;
 public  static final int FIX_FLD_NoMsgTypes     =384;
 public  static final int FIX_FLD_MsgDirection    =385;
 public  static final int FIX_FLD_NoTradingSessions   =386;
 public  static final int FIX_FLD_TotalVolumeTraded   =387;
 public  static final int FIX_FLD_DiscretionInst    =388;
 public  static final int FIX_FLD_DiscretionOffset   =389;
 public  static final int FIX_FLD_BidID      =390;
 public  static final int FIX_FLD_ClientBidID    =391;
 public  static final int FIX_FLD_ListName     =392;
 public  static final int FIX_FLD_TotalNumSecurities   =393;
 public  static final int FIX_FLD_BidType     =394;
 public  static final int FIX_FLD_NumTickets     =395;
 public  static final int FIX_FLD_SideValue1     =396;
 public  static final int FIX_FLD_SideValue2     =397;
 public  static final int FIX_FLD_NoBidDescriptors   =398;
 public  static final int FIX_FLD_BidDescriptorType   =399;
 public  static final int FIX_FLD_BidDescriptor    =400;
 public  static final int FIX_FLD_SideValueInd    =401;
 public  static final int FIX_FLD_LiquidityPctLow   =402;
 public  static final int FIX_FLD_LiquidityPctHigh   =403;
 public  static final int FIX_FLD_LiquidityValue    =404;
 public  static final int FIX_FLD_EFPTrackingError   =405;
 public  static final int FIX_FLD_FairValue     =406;
 public  static final int FIX_FLD_OutsideIndexPct   =407;
 public  static final int FIX_FLD_ValueOfFutures    =408;
 public  static final int FIX_FLD_LiquidityIndType   =409;
 public  static final int FIX_FLD_WtAverageLiquidity   =410;
 public  static final int FIX_FLD_ExchangeForPhysical  =411;
 public  static final int FIX_FLD_OutMainCntryUIndex   =412;
 public  static final int FIX_FLD_CrossPercent    =413;
 public  static final int FIX_FLD_ProgRptReqs    =414;
 public  static final int FIX_FLD_ProgPeriodInterval   =415;
 public  static final int FIX_FLD_IncTaxInd     =416;
 public  static final int FIX_FLD_NumBidders     =417;
 public  static final int FIX_FLD_TradeType     =418;
 public  static final int FIX_FLD_BasisPxType    =419;
 public  static final int FIX_FLD_NoBidComponents   =420;
 public  static final int FIX_FLD_Country     =421;
 public  static final int FIX_FLD_TotNoStrikes    =422;
 public  static final int FIX_FLD_PriceType     =423;
 public  static final int FIX_FLD_DayOrderQty    =424;
 public  static final int FIX_FLD_DayCumQty     =425;
 public  static final int FIX_FLD_DayAvgPx     =426;
 public  static final int FIX_FLD_GTBookingInst    =427;
 public  static final int FIX_FLD_NoStrikes     =428;
 public  static final int FIX_FLD_ListStatusType    =429;
 public  static final int FIX_FLD_NetGrossInd    =430;
 public  static final int FIX_FLD_ListOrderStatus   =431;
 public  static final int FIX_FLD_ExpireDate     =432;
 public  static final int FIX_FLD_ListExecInstType   =433;
 public  static final int FIX_FLD_CxlRejResponseTo   =434;
 public  static final int FIX_FLD_UnderlyingCouponRate  =435;
 public  static final int FIX_FLD_UnderlyingContractMultiplier=436;
 public  static final int FIX_FLD_ContraTradeQty    =437;
 public  static final int FIX_FLD_ContraTradeTime   =438;
 public  static final int FIX_FLD_ClearingFirm    =439;
 public  static final int FIX_FLD_ClearingAccount   =440;
 public  static final int FIX_FLD_LiquidityNumSecurities  =441;
 public  static final int FIX_FLD_MultiLegReportingType  =442;


Resend Confirmation

With this facility you can specify a list of messge-types in the fix engine properties file, for which confirmation will be sought if a message of that type needs to be resent. 

E.G. if you place the following entry in the properties file 

confrimResend  B 

If a B (News) message needs to be re-sent because the remote Fix Engine has requested a resend, Your FixHandler’s  onRequestResend(FixString fixMsg) will be called with the message as a parameter; if you return true, the message will be resent, if you return false the message will be replaced with a gap-fill.

NB: under normal circumstances all resends occur transparently to the application, but in some circumstances, you may not want to resend a message if market conditions have changed significantly since the time that the message was originaly sent. 


FixGW Error Handling Strategies

The Fix Gateway is a separate process running the fix communication protocol with a remote Fix Engine. The user application communicates with the Fix Gateway via a socket. If the line drops between the Fix Gateway and the remote Fix Engine, the user application must be notified, and any messages that the User application has sent before the error notification must be guaranteed to arrive at the remote Fix Engine. This section explains how this is achieved. Note, the afitest and afisrv utilities can be used to test the system's terror handling capability.

Connection Errors While Sending Messages

When the FixSession.sendMsg() is called, the message is sent to the Fix Gateway via a socket,  provided no error occurs in the call to send the message on the socket, FixSession.sendMsg() returns successfully. The problem is, that the line between the Fix Gateway and the remote Fix Engine may have dropped, but the SendFixMsg method does not detect this. (NB: sendMsg could query the state of the FixEngine but this would slow things down too much).

In the Fix Gateway process, when a message is received via FixSession.sendMsg() it is sent to the remote Fix Engine - if the line to the remote Fix Engine is down, the message is added to the fix Journal file, and the outgoing sequence number is incremented so that when the connection is re-established, the message will be requested by the remote side. When this happens, an Out-Of-Band message is sent back to the User Application setting and error state flag. FixSession.sendMsg() checks  the error state flag, and if it finds it set, it returns an error. The consequence of this strategy is, some messages may be sent when the fix connection is down, but this should only be one or two messages before the User Application is detects the error, and these messages are not lost, they are transmitted as soon as the fix connection is re-established.

If the User Application is waiting for a Fix Message and the fix connection drops, an internal fix-admin messages is sent to the User Application to notify it of the error condition straight away.

Sending Messages Using Buffers

The fixgw library implements a buffering facility which enables your application to send messages to a local buffer rather than sending them to the gateway, then when happy with the current application state, the application can flush the buffer to the gate way. If the line goes down or the application is killed while flushing the buffer, the current position in the buffer is remembered when the application restarts, and by calling FixClient::SynchronizeOutputBuffer(), your application can being sending from the point at which it stopped. Once the buffer has been flushed you should call FixClient::SetComplete() (provided you haven't previously called FixClient::DisableAutoRecovery(), in which case you never need to call SetComplete(). )

The FixSession.setComplete() method

Once you receive a Fix Message, the fix protocol is done with it, your application should then store it into a database soon as   possible so that if your application is killed or crashes, the message is not lost. 

Imagine the situation where your application is slow (for whatever reason) to processes messages it received. The Fix Engine  process will continue to send you messages until your application (socket) buffers are full. If at this point your   application crashes the messages in the application buffer will be lost, but as far as the Fix protocol layer is concerned, the message   will have been received successfully and will not be re-requested. SetComplete() protects your from this  roblem. 

When the AFI Fix Engine starts, it checks its last received sequence number with the one specified in the last call to setComplete(). If the SetComplete sequence number is lower, it checks in the Receive Journal and if the missing messages are there, it sends them to the client app(with the Possible Dup flag set to Y), and all should be well. If the messages are not in the Receive Journal, the Fix Engine sets its own expected sequence number to the one specified by  setComplete() thus  forcing a re-send of any 'lost' messages. By the remote side. NOTE: the messages should only be missing from the Receive Journal if the Receive Journal has been switched off. (If you do switch the Receive Journal off, be   aware, that,  if the missing message was time-sensitive, the remote Fix engine may decide not to re-send the message, but rather, replace it with a gap fill.

The best way to use setComplete()is to save the message in the database as soon as your receive it, and then call   setComplete(). Then, when your application re-starts, it should check the database for received but un-processed messages first,  process these, and then create the Fix session and continue as normal. 

You may decide to only call setComplete() when you have fully processed the message, e.g, if you are collecting  messages in a list.  If your application crashes with unprocessed messages in its list, the SetComplete mechanism  will ensure that these messages are  not lost. Doing this removes the need to save the message immediately into the database.

You may call  setComplete() after each message has been processed, or after a sequence of messages have been processed,   once called, it applies to all messages received since the last call. It is, however, probably  safest to save each   message as you receive it and call setComplete() after each successful save. 

If you don’t want to use SetComplete()at all, just call DisableAutoRecovery(true) as soon as the session is created.
 


The Script File Format

The FixSession.RunScript() method accepts a script file that contains a set of fix messages and sends them to the Fix gateway. The script file should contain  lines in the following format

BEGIN fixMsgType
This defines the start of a fix message - fixMsgType can be either the actual value of a fix message or a symbolic name as defined in <fixconst.h>, but without the leading FIX_MSG_, i.e. fixMsgType could be E or Order_List

fixFieldId  value
This adds a field to the current fix message - fixFieldId can be the numeric or symbolic id, e.g. 38 or OrderQty, value can be any string, it can contain embedded spaces if it is surrounded by double or single quotes. If the value is a fix-time or fix-date, value can be @N, this is interpreted as the current time plus N seconds, or %N which is interpreted the current date plus N days. If a unique id is required for any value, a & can be used at the start of the string - the & is replaced by the Hour/ Minute/Second at the time the script file began to run, in the form of HHMMSS, the rest of the value is then appended to the HHMMSS - in this way & represents a different value each time a script runs, but the same value for the lifetime of the script. Note for & to be expanded into HHMMSS, it must appear at the start of the string.

If, however, more than one script runs in a second, the &  value will not change. For this reason there are several substitution characters that can be used, but note they must appear at the front of the string

& … substituted with HHMMSS
^  … substituted with HHMMSSmmm where mmm is the current milliseconds value, giving a unique value on a dily basis.
|   … substituted with the number of seconds since 10/10/2001 (in hex), thus | should give a
         unique  8 character value over time provided the script doesn’t run more than once per second.
~ …  substituted with  XXXXXXXmmm where XXXXXXX is the number of seconds since 10/10/2001 in hex and
         mmm is the current milliseconds value,  thus ~ should give a unique 10 character value over time 
         regardless of how quickly the scripts run.

SEND
Send the current fix message to the fix gateway.

RESET_AMPERSAND
Reset the value used when substituting &. This will be reset to the current hour/minute/second - note: the substitution values are automatically reset each time a script runs.

SET_AMPERSAND value
Set the value used when substituting &. The value parameters can be any string. Ampersand substitution is designed to enable the same script file to generate different ID's on each run, but you may, temporally, wish to test what happens when you get 2 runs with the same IDs, in this situation, you can use the SET_AMPERSAND at the top of the script to set a fixed value that will remain the same on each run of the script.

LOAD_AMPERSAND
This command loads a previously saved ampersand (&) value from persistent  storage. If there is not a previously saved value, the ampersand value  is set to 000000. Typically, you will LOAD_AMPERSAND and then INCR_AMPERSAND at the start of the script, and SAVE_AMPERSAND at the end, thus guaranteeing a unique value for ampersand on each script run. Values of ampersand loaded like this will be zero-padded to 6 character positions.

SAVE_AMPERSAND
You can save the current value of & to persistent  storage with this command.

INCR_AMPERSAND
Increment the value of the & substitution, if this is not a numeric value, a value of 0 will be used

DECR_AMPERSAND
Decrement  the value of the & substitution, if this is not a numeric value, a value of 0 will be used

RESET_HAT
Reset the value of the ^ substitution

RESET_BAR
Reset the value of the | substitution

RESET_TILDE
Reset the value of the ~ substitution

BEGIN_BUFFER
All subsequent messages are sent to the buffer, rather than the fix gateway.

FLUSH_BUFFER
Flush  the output buffer, sending buffered messages to the gateway. Subsequent messages are sent directly to the gateway unless BEGIN_BUFFER is called again.

#
This is a comment

A simple script file, to send 2 orders in a list would look like this...

# example script file
BEGIN Order_List
    ListID &4
    ListSeqNo 1
    ListNoOrds 2
    ClOrdID  &01
    ClientID ZCN0002
    Account xxxxxxxxx
    FutSettDate %2
    Symbol OCT.L
    SecurityID 12345678
    IDSource 2
    Side 2
    OrderQty 20000
    Price 987
    Currency GBP
    TransactTime @0
    TradeDate %0
SEND
BEGIN Order_List
    ListID &4
    ListSeqNo 2
    ListNoOrds 2
    ClOrdID  &02
    ClientID ZCN0002
    Account xxxxxxx
    FutSettDate %2
    Symbol OCT.L
    SecurityID 12345678
    IDSource 2
    Side 1
    OrderQty 20000
    Price 987
    Currency GBP
    TransactTime @0
    TradeDate %0
SEND

The afisrv Tool

This tool allows you to run fix client or server sessions with a minimum of effort. The tool understands a simple script format whereby you can send fix message to whoever is connected. The source code for this tool is included as a sample. The tool presents a character-based menu for simplicity and portability, and allows you to 'open' any config file you require. The program can act as a server and/or a client - two versions of the program can run on the same machine and communicate with each other. For testing purposes a configuration file named testsrvr is supplied, this configuration sets the fix gateway into server mode. A second configuration, loopback, is supplied for testing purposes, this config is used by the afitest sample program, which simply connects to the afisrv on the local machine. You can then send heartbeats and other fix messages to afitest from the afisrv menu, and watch them appear. This tool is particularly useful when testing your applications, you can create a script-file with a set of standard fix data and run afisrv as a dummy, replacing the actual Fix Engine you will want your application to connect to.

afisrv displays the following character based menu...

    o) Open Session         c) Close Session
    h) Send Heartbeat       t) Send Test Request
    s) Send Script File     n) Send Test News
        r) Reset Session        q) Test Reset Seq Num

    v) verbose mode

    x) exit

o) open session
This option prompts for the name of a config file, the default value is testsrvr, this implements a server that will listen for incoming connections. The fix session runs in a separate thread leaving a user interface thread free to process menu commands. The c)close session option can be used to close the session.

h) send heart beat
Send a fix heartbeat to the remote fix engine.

t) send test request
Send a fix test request to the remote fix engine - we should get a heart beat in response, which will be seen if verbose mode is on.

s) run script file
Run a script file, 5LISTS.TXT is prompted for by default.

n) send test news
A test news message is sent

r) reset session
cause both sides to reset their sequence numbers back to 1. This will only work if both sides of the fix session are running protocol version 4.2 AND the fix gateway config file must have ManualSessionSwitch set to 0.

q) test reset sequence numbers
The sequence numbers are reset from 100.

v) set verbose mode
Verbose mode switches of the display of the menu, but displays all incoming fix messages as they are received. Menu commands are still processed, and entering v again will switch verbose mode off.

If you select the s) option, you will see the following sub menu

  2) 2 Orders Sample script
  5) 5 Orders Sample script
 OR  the name of a script file

This allows you to easily run the sample scripts or any script of your own. If you want to run your own script, just type its name.

The source code for this tool is included as a sample.


The afitest Sample

This is a simple test program, the source for which is included in the distribution. This program also display a simple menu, as follows...

afitest menu

0) normal mode
1) none buffered mode
2) local client crash-simulation testing mode
3) local gateway crash-simulation testing mode

4) test File fix-msg-source and fix-msg-destination

x) exit

To run the test, first start afisrv, and take the (o)open menu option and open the testsrv session - this is the default session to open, so you shouldn't have to type in its name, just accept the default. Now, from a different command line window, start the afitest program - it will give you a small menu, choose option 0. In order to give afitest some work to do, return to afisrv and take the (s) send script file menu - you will be able to chose from the pre-defined scripts 5LISTS.TXT (option 5), 2LISTS.TXT(option 2) or enter your own script file name. Running5LISTS.TXT script sends lists of orders to afitest, which simply compiles these lists into a file, and sends acknowledgements back to the sender. It is a relatively trivial test, but demonstrates many features of the fixgw lib. It can be used to test recovery features in the event of a system failure, as afitest validates the file it creates, and afisrv validates the replies it receives - the validation is based on the FIX_FLD_ClientID which is set in ascending order in 5LISTS.TXT.

The main point of interest in afitest is the ProcessFixMsg(FixString &sfix, FixClient &fixcli), where the messages are complied into lists. and void ProcessNews(FixString &sfix, FixClient &fixcli, StringType &orderList) where NEWS messages are handled - the 2 test programs use NEWS messages to trigger certain actions.

Note: if you select option (0), you will be invited to "RELEASE VALIDATION FILES", if you are running a normal test you should enter Y and do this. You should  not do this if you are testing a recovery after a previously simulated crash.

Simple afitest / afisrv Test Session

This session will involve connecting the afitest program to the afisrv program via a fix session. They will exchange messages and verify that all messages have arrived successfully. afitest will use the loopback configuration file, and afisrv will use the testsrvr configuration file. Both thes config files are supplied with the distribution, in fact afisrvr can load any configuration file you choose, but afitest can only access the loopback config.
(afitest)...(FixGatwWay,cfg:loopback) -----//----- (FixGatwEay,cfg:testsrvr)...(afisrv)
 Just follow the simple instructions bellow to run a test fix session...
  1. Start afisrv and afitest. These programs are both windows console applications.
  2. Select option (o) from afisrv and then just hit return at the next prompt.
  3. Select option(0) from afitest and enter Y at the next prompt
  4. In afitest, selectoption (s) and enter 5 at the next prompt
  5. You should see messages scrolling in the afitest window. After a few seconds you should see the message ORDER FILES VALIDATED AND SAVED in the afitest window, and [TEST LOG VERIFIED OK]in the afisrv window
  6. Enter x in the afisrv window to close the session.
  7. afitest will detect that afisrv has closed, enter a q to close afitest.

Using afitest and afisrv To Test The System's Error Recovery Capabilities

Note: in following discussion afitest is used to refer to the afitest client application and the associated fixgw process, and similarly afisrv refers to the afisrv client application and the associated fixgw processes. Remember, self validation during these tests rely on the fact that 5LISTS.TXT script files supplied wi