This package is complementary to the FixGateway package. The FixGateway
package implements a FIX engine and includes C++ (and ActiveX) programming
interfaces. This package provides a C# (.NET) programming interfaces to
the FixGateway FIX engine, it does not include the FIX engine itself, you
also need the FixGateway package.
For more information about the FIX Protocol see http://www.fixprotocol.org
Release 18 or higher of the FixGateway is required by this interface
package. This release of the FixGateway also includes support
for FIXML.
Contents
For more detailed implementation information, see the FixGateway
documentatio documentation. Note: all 3 APIs (C++, C#, Java) provide
the same functionality in essentially the same way, however, they
are all fully independent, i.e. neither the C# nor the Java interfaces
use use each other or the C++ interfaces.
System Components
There are 2 system components, a FixGateway process (or Fix Engine) that
is started automatically when needed, and the CsFixGW assembly that
provides a programming interface to the Fix Engine.
Only the CsFixGW assembly is included in this package, to use
the rest of the components, you also need the FixGateway
process which is included in the FixGateway package.
Getting Started
You must use the namespace CsFixGW and include a reference
to the CsFixGW assembly in CsFixGW.dll. The standard pattern
of a fix gateway application is a message loop which sends and receives
fix messages. The following is the basic structure of the CsFixTest
sample application
// CsFixTest...
using CsFixGW;
...
String configName = "loopback";
// loopback is a standard
config file supplied with the distribution, it
// allows a fix client
(namely fixtest) to connect to the CSFixSrv
application
FixClient fixSession = new FixClient();
int ok = fixSession.Open(configName);
if( ok != FixError.FIX_OK )
// report error
ok = fixSession.SynchronizeOutputBuffer();
// you only need to make
this call if your application
// uses the BufferedOutput
methods; this ensures that
// if your app crashed
while processing BuffereOutput,
// the messages are not
lost - if the remote fix gateway
// is not yet connected,
the messages will be stored
// internally until a
connection is made
// you could make this call here if you wished,
// but there is no requirement to...
// ok =fixSession.WaitForConnection();
// this is probably of
more use when running
// the fix gateway as
a server
FixString sfix = new FixString();
for(;;)
{
FixError ok = fixSession.GetFixMsg(sfix);
if( ok != FixError.FIX_OK )
break
String msgType = sfix.GetMsgType();
if(msgType.Equals(FixConst.Some_message_type)
)
{
// process the message
...
}
fixSession.SetComplete();
// must call this once you are happy that a
// fix message has been fully processed
}
Your application will be in a fix message loop, if your application needs
to process Windows events, the best thing to do is put the fix message
loop in a worker thread, leaving the User Interface thread free.
If you need your User Interface thread to communicate with your Fix Message
thread, e.g. to close the fix session, you can create a CntrlInterface
object in the User Interface thread and pass it to the FixClient object
in the worker thread. You can then pass messages to the worker thread by
using the CntrlInterface object in in the User Interface thread. The CsFixSrv
sample application uses this technique and implements a Simple (character
based) User Interface thread and a Fix Worker Thread. The following code
fragment demonstrates the technique.
// CsFixSrv
using CsFixGW;
...
/*
**user interface thread
*/
CntrlInterface ctrl = new CntrlInterface();
ctrl.InitControlSide();
// create worker thread here, passing
in pctrl
// NB: if you have more than one worker thread,
each must have a
// different control interface, they cannot
share a common control
// interface!
ctrl.WaitForActivation(); // still in client
thread
// this returns when the worker thread is active, i.e. before
// a connection to another fix engine has been established
/*
**worker thread
*/
String configName = "testsrvr";
// testsrvr is a standard
configuration file supplied with the distribution, if
// the fixgwsrv application
loads the config, it will run as a Fix Server, and
// can be connected to
by any fix client, in particular, the fixtest sample
// application
fixSession.DisableAutoRecovery();
// calling this avoids
the need for calling SetComplete(), but
// if the system crashes
while processing a message, the message
// will be lost - it MUST
be called before OPEN if it is to be effective
FixClient fixSession = new FixClient();
int ok = fixSession.Open(configName, ctrl);
//
ctrl is created in the UI thread, and passed to the worker,
//
// NB: if configName is already open in this process or any other
// process, an error will be returened here - multiple fix sessions
// are permitted in one process or in multiple process but not multiple
// sessions using the same config!
if( ok != FixError.FIX_OK )
// report error
// the session is now open, i.e. the gateway
procss has been created without
// errors, and, if running as a server, (as
it is in the CsFixSrv sample),
// it is waiting for another Fix Engine to
conect to it
ok = fixSession.WaitForConnection();
// this is an optional
call introduced in reales 5, it returns
// only if a connection
has been made with another Fix Engine,
// if an error occurs,
or if a control message has been sent
if( FixError.IsControlMsg(ok) )
// procss control message
else if( FixError.IsError(ok) )
// report error
FixString sfix = new FixString();
for(bool loop=true;loop;)
{
ok = fixSession.GetFixMsg(sfix);
if( FixError.IsControlMsg(ok) )
{
short ctlMsg = fixSession.GetControlMsg();
//
process control message sent from UI thread
}
else if( FixError.IsError(ok) )
{
//
fix session terminated
}
else
{
String fixMsgType =
sfix.GetMsgType()
//
process fix message
}
}
The CsFixGW Assembly
The CsFixGW assembly is implemented in CsFixGW.dll, to
see how to link this to your applications, see the Samples provided with
the installation
Note the int return values are defined by constants in the
FixError
class, in all cases FixError.FIX_OK indicates success
using CsFixGW;
new FixClient()
Create and initialize a FixClient object. The object is not connected
to the fix gateway until Open() is called.
Destruct()
You can call this method to close the connection and release
any resources. If you just call Close(), some resources are held
in case you want to Open() the connection again. If you don't
call Destruct(), the resources will be released when (if) the
garbage collector runs and calls the objects finalize() method.
int Open(LPCTSTR configFile)
int Open(LPCTSTR configFile, CntrlInterface ctrl)
Open a fix session. The parameters of the fix session, e.g. IP address,
port etc., are held in the configFile. The config file can be a full pathname,
but more usually, it is just the filename, without extension - given such
a value, the fix gateway will look (under UNIX) in /Octatec/fixgw/Home/configs(and
under WIN32) in C:/Program File/Octatec/fixgw/configs for
a file of the same name and a .cfg extension. If you choose to
use the full path specification for config files, the path length must
be less than 128 characters. (You should try and keep config names (not
path names) less than 32 characters, as the config file name will be truncated
to 32 when the log-directory is created). Use the ctrl parameter
if you want to send control mesages to a worker thread in a Fix Message
loop.
The same application can have many FixClient objects, and open multiple
fix sessions if it wishes, however, it should only Open
a configFile once, i.e. if you wish to open 2 or more
sessions to the same client, you must create separate config files for
each session, the files can just be copies but must have different names,
e.g. MyBroker_1,
MyBroker_2 etc. The reason for this
is that the configFile name defines where the fix log files are
created. Attempts to open the same configFile more than once in the same
process or even in a different process will fail.
int WaitForConnection()
You may use this method to wait until a connection has been established
with the remote fix engine. The method only returns when (a) the Local
Fix Gateway makes a connection to a remote Fix Engine, or (b) if an error
occurs, or (c) if the CntrlInterface is in use and a Control Message has
been sent by another thread. You do not need to make this call, you can
go straight into reading messages or sending messages, (if messages are
sent and no connection is ever established, they are not lost, they are
stored in the local Fix Gateway, if you try to read before the connection
is established you will just wait until the connection is made). This method
is, perhaps, of most use when the local Fix Gateway is acting as a server.
bool IsConnected()
This method returns true if the local Fix Gateway is connected to a
remote Fix Engine.
int GetFixMsg(FixString str)
This is the main method of the object. Your program should enter a
loop calling GetFixMsg() until it returns an error. When the method
returns without an error, the str parameter contains a
fix message. You should query the returned FixError object to
see if the message returned was a Fix Message, or a Control
Message. Mostly, it will be a Fix Message. If it is not
a fix message, the str parameter is meaningless and you
must use GetControlMsg() to get the ControlMessage
information.
int SendFixMsg(String type, FixString str)
This method is used to send a FixMessage to the remote fix engine.
You should set the fix-fields of the str parameter and
then send the message. The type parameter should be one
of the
FIX_MSG_ values defined in the in FixConst
class,
or
any other string value denoting a locally agreed fix message type.
int ResetSession()
This resets sequences numbers back to 1 on both sides of the conversation,
using the Reset Session mechanism introduced in protocol version 4.2. If
the protocol version is bellow 4.2, this method returns an error. When
the session is reset, a new log directory is created.
For this method to work, ManualSessionSwitch must be set
to 1 in the config file.
int ResetLogLevel(int n, bool gatewayOnly)
This method can be used once a connection is established to reset the
log level, valid values are 1 2 or 3. If gatewayOnly
if
false, then the client log level is also reset.
int ResetForwardHtBtFlag(bool flag)
This method can be used once a connection is established to reset the
heartbeat forwarding strategy, if flag is true,
heartbeat messages are passd to the client app.
int ResetRejectionTolerationLevel(int value)
This method can be used once a connection is established to reset the
rejection toleration level. If the value is 0, rejections
are always allowed, otherwise, the gateway will close down after receiving
the specified number of rejections. A value of 1causes
the gateway to close immediately it receives a rejection from the remote
Fix Engine.
int ResetForwardRejectionFlag(bool flag)
This method can be used once a connection is established to reset the
rejection forwarding strategy, if flag is true,
fix-protocol rejection messages are passd to the client app.
int ResetManualSessionSwitchFlag(bool flag)
This method can be used once a connection is established to reset the
ManulSessionReset
flag (see the FixGateway documentation
for more details about this flag.) If flag is true,
and
the fix version is 4.2 or above, a new fix session will
only be
started if either side initiates a new session (using ResetSession).
int BeginBufferedOutput()
After this method has been called, SendFixMsg() merely
records the message in a local persistent buffer.
int AbortOutputBuffer()
This method closes and discards the local buffer.
int FlushOutputBuffer()
This method closes the local buffer, and then sends all messages to
the fix gateway. As each message is sent, it is marked as processed,
so that if your application fails or is killed, when it restarts, you can
use SynchronizeOutputBuffer() to send any pending messages
to the gateway. Once FlushOutputBuffer() or AbortOutputBuffer()
is
called subsequent calls to SendFixMsg() sends messages
directly to the gateway, until BeginBufferedOutput()
is
called again.
The CsFixTest sample demonstrates the use of
output buffering and SetComplete().
int SynchronizeOutputBuffer()
You can use this method when your application starts, it will send
any pending messages in the local buffer to the gateway. You should only
have pending messages if your application failed or was killed. If
you make use of the buffering mechanism, you should call this method immediately
after Open() returns success.
bool SetComplete()
This method tells the system that all messages received since the last
call to SetComplete() (or since the 1st message was received
if SetComplete() has not yet been called) are fully processed.
Until SetComplete() is called, all messages currently received
will be received again should your application crash or be killed. Depending
on how your application is structured, you may call SetComplete()
after
each message has been processed or wait until a group of messages, i.e.
a list, have been processed. SetComplete() is implemented
by saving the sequence number of the last completed message, and then passing
this to the gateway at startup - the gateway compares this to the last
application-level message received, and if it is lower, the gateway requests
a resend from the remote fix engine. If you call DisableAutoRecovery()
there is then no need to use Setcomplete(), but this
is not recommended.
bool SetComplete(int lastProcesedSeqNum)
This form of SetComplete() allows you to set which
sequence number you are 'happy' with. You can extract the sequence number
from the Fix Message.
void DisableAutoRecovery() // implies mode==true
void DisableAutoRecovery(bool mode)
This method disables the SetComplete() mechanism. However,
doing this is dangerous, since if your application (not the fix gateway)
crashed or was kill after it received the message but before it was processed,
the message would be lost, as the fix gate will have received it successfully
and passed it to your application successfully as well. It must
be called before Open() if it is to be effective.
int Close() // implies grace=15
int Close(int grace)
Close the fix session. If you do not close an open session, it will
be closed eventually by the finalize method, but because you don't know
when this will run, you should always Close sessions
explicitly. If you open a 'server session', and try to close it before
a client has connected to it, you will hit a snag - the gateway is
'busy' waiting for a connection, and will not see the 'close' command,
consequently, the Close() method will wait up to grace seconds before forcibly
closing a 'server' GateWay if it doesn't close naturally.
The Close method keeps some resources allocated in case you want to Open
the connection again. If you don't want to open the session again, you
can call Destruct() after Close(), or just call Destruct() without calling
Close().
int Reopen()
If you get an error from GetFixMsg() or WaitForConnection()
you can either call Close() and Open()
or just call Reopen(). If you get an error from Reopen(),
then you should call Close() and Open().
If you call Close(), Reopen() will not
work and you must call Open(). Any additional login
or header tags you have set will still be active after a Reopen(),
but will not be active after a Close(). NB: Reopen()
will
return an error if no connection has ever been established, i.e. it should
be used after a connection has been established and then closed by the
other side.
int RunScript(final String path, out int numberOfMessages) //
implies reconnect=0 maxretries=0
int RunScript(final String path, out int numberOfMessages, int
reconnect, int maxretries)
Run a script, the number of messages processed is returned in numberOfMessages.
See
the FixGateway documentation
for the format of a script file. If reconnect is specified,the
fix session is automatically reconnected after waiting reconnect
seconds
- this process is repeated for maxretries times (or forever
if maxretries is 0). Note: if the configuration specifies
the fix gateway is in server mode, the reconnect will cause the gateway
to wait for another connection. You may pass -1 as the reconnect parameter,
in which case their is no delay before the reconnection attempt - you may
want this if your fix gateway is acting as a server. (see the
configuration
file section for how to configure the gateway as a server)
int OverrideTargetSubId(final String newId) // implies permanent=true
int OverrideTargetSubId(final String newId, bool permanent)
You can use this method once a connection has been established to override
the TargetSubID defined in the config file. If permanent
is false, the change is only applied to the next message
you send, otherwise it is applied to all subsequent messages (resent messages
are, of course, resent with their original TargetSubID)
int SetAddionalLoginTags(final FixString tags)
This method can be used before the FixClient::Open() call to
define some additional fields to be sent in the Login message - i.e. this
can be used to support non-standard login tags.
int SetAddionalMsgTags(final FixString tags)
This method can be used before the FixClient::Open() call to
define some additional fields to be sent in all outgoing messages
- i.e. this can be used to support non-standard header/trailer tags (actually
the tags are always added to the end of the message, but before the standard
fix trailer).
int ResetSessionAtLogon();
This method van only be used before a connection is established, i.e.
before the Open() call has been made. This instructs the
system to include a reset-sequence-number directive with the initial logon.
The sequence numbers will be reset to zero on both sides. This can only
be used, of course, if the sequence numbers are already ‘in-sync’ to start
with. This method can only be used with Fix 4.1 and higher.
int ResetSequenceNumber(int num)
This method provides an interface to the Fix Protocol RESET SEQUENCE
NUMBER message, sequence numbers can only be increased in value, so
the num parameter is added to the current value of the
outgoing sequence number. NOTE: you shoukld not attempt to send this
FIX message yourself, if you want to send the message, use this method,
however you are very very unlikely to actually want to do
this, you are very very unlikely to find this method useful
for any purpose!
void GetControlMsg(OutputShort &msg, OutputString &s)
String GetControlMsgString()
short GetControlMsg()
These methods return the value of the control
message (and it's string parameter, if one was present)
Socket GetControlInterface()
This can be used if a ControlInterface is in use and
you wish to send a response back using CntrlInterface.SendResponse()
- the control messages values/contents are chosen entirely by you,
but the intention is that they be used for simple queries and
shutdown commands.
public Socket DetatchControlInterface()
Detatch the ‘raw’ Control Interface socket. The purpose of doing this
is so that the socket is not closed by the FixClient::Close()
method. You can then close the FixClient and the Control Interface
held by the UI thread remains valid. Thus if you decide to open another
FixClient
object, you can ‘reuse’ the Control Interface without having to inform
the GUI client. The CsFixSrv sample shows the usage of this call.
public bool AttachControlInterface(Socket csd)
Attach a previous detatched ‘raw’ Control Interface. This call MUST
be made before FixClient::Open() is called, otherwise it
will fail. (If you pass a Control
Interface Object in the Open() call, then that is the
interface that will be used, and the previously attached ‘raw’ interface
will be ignored.)
int SetRecoverySeqNos(long out) // implies in = -1
int SetRecoverySeqNos(long out, long in)
This method can be used to recover a connection after complete sequence
number failure. To achieve this you must call this method before Open(),
probably with out = 899999 and the default in parameter.
After the connection has been established, the session will be automatically
reset, and both sides will have sequence numbers of 0. IMPORTANT:
do not use this method as a 'matter -of-course' - only use it to recover
the situation described here. This method can only be used with Fix 4.2
and higher.
bool IsGmtOffsetInUse()
If a Virtual Timezone is being used in the Gateway process,
this method returns true. (To find out more about Virtual Timezones,
see the FixGateway documentation)
short GetGmtOffset()
If a Virtual Timezone is being used in the Gateway process,
this method returns the offset from GMT of the Virtual Timezone.
If no Virtual Timezone is in use, a value of Config.V_LOCAL_TIME
is returned. To find the time as viewed by the gateway process, use the
FixString.GetCurrentTime() method.
int ConfirmResend(bool okToResend)
Call this method in response to a Resend Confirmation Request.
You can configure the system to ask for confirmation when resending
time-sensitive messages. (To find out more about Confirmation Requests,
see the FixGateway documentation)
FixError Static Constant Values
FIX_OK (0)
no error
FIX_LOGOUT (-1)
the remote side logged out
FIX_DROPPED (-2)
the remote side droppend the line
FIX_CANT_CONNECT (-3)
can't connect to the remote
FIX_NO_CFG (-4)
the config file specified does not exist
FIX_NO_GTWY (-5)
the gateway process cannot be started
FILE_OPEN_ERROR(-6)
couldn't open the config file or an
inpuit/output file
FIX_IN_USE(-7)
the configFile specified in
the open call is already opened in this or another process.
FIX_BAD_DYN_CFG (-8)
you passed a DynamicFixCfg
object to FixClient::Open(), and DynamicFixCfg::Save()
failed.
FIX_BAD_ID (-9)
the other side of the
Fix Conversation has an unexpected ID or SubID, the IDs of the sender are
specified in the config file, and are
called
the TaregetID and TargetSubID,
these must match what the Sender actually sends, similarly our IDs may
well be checked by the Sender,
these are called the
LocalID and the LocalSubID in the config
file.
FIX_OUT_OF_SYNC (-10)
The gateway process is
issuing resend requests but the remote fix engine is rejecting these requests
FIX_BAD_FIX_VER (-11)
The gateway process detected
an incompatible Fix Version specified in the config files.
NO_ADMIN_INTERFACE (-1000)
this error can only occur when trying
to 'run' a script
or journal file, and
the session is not correctly initialized
NO_FILE (-1001)
the script or journal file you are trying
to run does not exits
WRONG_PROTOCOL_VERSION (-1003)
a session reset was attempted but this
is not allowed in the current protocol version
FIX_CLT_IF_ERROR (-992)
FIX_SELECT_ERROR0 (-993)
FIX_SELECT_ERROR1 (-994)
FIX_INIT (-996)
internal errors
FIX_ERROR (-999)
a general error
FIX_CONTROL_MSG (1)
not an error, and indication that the
message is a control message, not a FIX message
Methods
bool IsControlMsg(int errorCode)
Returns true if the input errorCode represents a
control message. (I.e. errorCode==FixError.FIX_CONTROL_MSG).
bool IsFixMsg(int errorCode)
Returns true if the input errorCode represents a
FIX message. (I.e. errorCode==FixError.FIX_OK).
bool IsError(int value)
Returns true if the input errorCode represents a
an error state.
This class allows you to pass messages from a controlling thread, e.g.
a user interface thread into the fix message loop of a fix worker thread.
Once in a Fix Message Loop, the thread is waiting for messages from the
Fix Gateway and/or messages from the Control Interface. Unless you use
the Control Interface, their will be no way for you to control the Fix
Message Loop except when a Fix Message arrives. The main reason for implementing
the Control Interface object is so that a GUI thread can tell the FIX thread
to shut down. The JFixSrv program shows how
the Control Interface can be used.
new CntrlInterface()
Create a new CntrlInterface object (in the UI thread)
bool InitControlSide();
Call this method first in the control (GUI) thread
bool WaitForActivation() // implies sendStartMsg=true
bool WaitForActivation(bool sendStartMsg);
Call this method in the Control (GUI) thread after the worker thread
has been created, it will wait for the worker (FIX) thread to become
'ready'. Once the worker thread is ready, provided sendStartMsg
was true, WaitForActivation() will send a start
message allowing the worker thread to continue and connect to the remote
fix engine. If sendStartMsg was false, you must manually
send a start message when the time is right.
bool SendStartMsg()
You only need send a Start Message after if you passed in false
to WaitForActivation(), if you did, you must call this
method at some point after WaitForActivation() returns
true.
This allows you to control when the Fix Message Loop actually begins.
bool SendMsg(short iparam) // implies sparam=null
bool SendMsg(short iparam, String sparam);
You can use this method to send messages to a thread in a Fix Message
Loop, the messages are entirely under your own control but should all have
values above 100, values below 100 are reserve for internal use. It is
intended that this mechanism be used for simple queries and commands,
e.g. to shutdown the gateway. The messages will be received in the Fix
Message Loop via FixClient.GetFixMessage(), a return of
FixError.FIX_CONTROL_MSG
fromFixClient.GetFixMessage()
indicates
that you should call
FixClient.GetControlMsg() and optionally
FixClient.GetControlMsgString()
to examine the message and any parameter. Normally, SendMsg()
will be called from the Control (GUI) thread to send a message to the worker
(FIX) thread, possibly to shut down, it is unlikely, but possible, you
may want to send a response to the message, to do this, use the SendResponse()
method
static bool SendResponse(Socket sd, short iparam) // implies
sparam=null
static bool SendResponse(Socket sd, short iparam, String sparam)
Call this method in the worker (FIX) thread to send a response back
to the Control (GUI) thread if you know one is required.
bool GetResponse(OutputShort iparam, OutputString s)
If you are expecting a response to the message, you can use this method
in the Control (GUI) thread to wait for it. Mostly, messages you send to
the fix thread will not give rise to a response.
This class provides the functionality for building fix messages and
accessing all the fields of the message. The class FixConstprovides
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 name, out String value)
bool GetField(int name, out Int value)
void AddField(int name, int value)
void AddField(int name, String value)
void UpdateOrAddField(int name, int value)
void UpdateOrAddField(int name, String value)
bool RemoveField(int name)
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.
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()
bool EnumNextField(out int name, out String 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 DateTime GetCurretTime() // implies gmtOffeset = Config.V_LOCAL_TIME
static DateTime 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(DateTime cal) // implies format = FixString.FMT_LONG_MS
static String FormatTime(DateTime cal, int format);
Convert the date in cal into a fix format string. 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 DataeTime 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.
Additional Config Parameters
All the config parameters described in the FixGateway
documentation are supported. There is also an additional config parameter
that is used in the client library.
ThreadSafeLogs n
(the default value is 0)
Normally thread safe logs will not be an issue. The class library
is thread-safe at the class level, i.e. you can use different FixClient
objects in multiple threads. However, if you use the same FixClient
object in different threads you need to synchronize your access to the
FixClient
object. In this case, you should set ThreadSafeLogs to
1,
and this will reduce the amount of synchronization you need to do. In general,
however, you should not need to access the same
FixClient object
from different threads – you may be tempted to call FixClient.GetFixMsg()
one thread and FixClient.SendFixMsg() on another. Our experience
has shown that this works with ThreadSafeLogs
set to 1,
however it is not the recommended way to proceed. The ControlInterface
object was designed to allow you to write to a FixClient object
from a thread other than the reading thread, i.e. instead of calling FixClient.SendFixMsg()
on the writing thread, call CntrlInterface.SendMsg(). If
you use the CntrlInterface you do NOT
need to set ThreadSafeLogs to 1, leave
ThreadSafeLogs
set to to the default value of 0.
Building The Samples
Firstly, the assembly, CsFixGW.dll is located in <installation
dir>\bin, which is C:\Program Files\Octatec\fixgw_cs\1.00\bin
by default.
Within the installation directory is a samples directory containing
subdirectories with the code for CsFixTest and CsFixSrvr.
Each of these has a bin director where the .EXE
is
located (there is a pre-built .EXE with the installation).
Also in the bin director is a .config file that allows
the .EXE to find the CsFixGW assembly when it runs
– your applications will need a similar .config file.
In each of the CsFixTest and CsFixSrvr directories there
are Make.cmd files that you can use to build the samples;
these .cmd files assume that the C# compiler is available
on the PATH.
The CsFixSrv 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 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 JFixTest
sample program, which simply connects to the fixgwsrv on the local machine.
You can then send heartbeats and other fix messages to fixtest from the
fixgwsrv 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 fixgwsrv as a dummy, replacing the actual
Fix Engine you will want your application to connect to.
CsFixSrv 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 displays a sub menu and prompts
for the name of a config file, the default
config of testsrvr can be used, 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. Thec) 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
This option will display a sub menu allowing
you top select a script file to run. The file, 5LISTS.TXT is
the default 'long' script and 2LISTS.TXT is the default short
script, either can be selected or your own script file can be used.
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) verbose mode
With this mode set, all incoming fix messages are displayed on the
screen.
The o) open Sub Menu
enter Path-name or...
t (for defualt 'testsrvr' config) or...
q (quit, don't open a session)
==>
Choose t for the default config, this will then allow the
JFixTest
application to connect to this server.
The s) script Sub Menu
Once a connection is established you can use this menu option to send
the contents of a script file
enter Path-name or...
5 (for defualt long script) or...
2 (for defualt short script) or...
q (quit, don't run script)
==>
The source code for this tool is included as a sample.
The CsFixTest 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...
0) Normal Test
1) Gateway Crash Simulation Test
2) Unexpected Exception Simulation Test
3) Non Buffered Test
x) Exit
==>
To run the test, first start CsFixSrv, 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
CsFixTest program
- it will give you a small menu, choose
option 0. In order to give
CsFixTest
some work to do, return to CsFixSrv 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. Running 5LISTS.TXT script sends lists of orders to
CsFixTest,
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 jfixgw.jar.
The FixGateway documentation has
more details on the usage of the C++ counterpars of CsFixTest
and CsFixSrv in more detail
Troubleshooting
In addition to the standard log, the system maintains a temp log
for recording errors tha occur when the main log is not available. The
main log file is typically not available before the config file
has been read and processed, e.g. if the path for the log specified in
the config file is invalid, or if the specified config file does not exists,
all these errors will be reported in the temp log.
The temp log is located in the application start-up directory, and is
called .fgwtemp.log; it is normally very small, and is
overwritten each time the application runs. If you create multiple FixClient
objects, all the messages will go to the same log. The temp log mechanism
is thread safe provided thread-safe logging is activated in the config
file.
|