TSE Access Library Interface and Usage Guidelines
Contents
TSE Access Library is a set of C++ components and interfaces designed to provide high-level access
to Tokyo Stock Exchange electronic trading systems using a number of instrument-specific protocols.
Library components manage physical and logical connections with TSE systems, allowing client to concentrate
on financial data manipulations. Library also provides representation of TSE protocol messages as a set
of C++ classes with access methods for all message fields specified by TSE protocol.
NOTE: In this document TSE Access Library refers to a set of components for managing trading session
with TSE Stocks Trading System. TSE Access Library for Futures, Options and Indexes trading system
differs only in financial data representation part.
-
Session control. Library is to provide efficient means to control and receive information about session.
-
Financial data representation. Design should allow easy manipulations with financial data.
-
Integration with client system. Library should set up minimum requirements for client systems.
The TSE trading system consists of a transaction server, which processes trading transactions, an
an intersystem relay server, which acts as a front end for TSE system, handles connections with member
systems, relays messages, etc., and a member (client) system.
A number of transaction servers can co-exist in the system, each processing several markets. Relay
server receives transactions and other messages from member system and delivers them to appropriate
transaction servers; it also collects notices from transaction servers and delivers them to member
systems.
Client system sets up a logical I/O device referred to as "virtual server", which is associated with
one market. Term "market" corresponds to TSE product code, available codes are listed in TSE
documentation. Examples of products are: stocks, futures, options, convertible bonds, etc. Each
virtual server is assigned an identifier (VSID) provided by TSE.
TSE session begins with a log-on procedure, during which virtual server sends a "Virtual Server Ready"
message and relay server responds with "Virtual Server Ready ACK" message. After virtual server receives
a VS Ready ACK message, it waits for information about current system and market status. This information
is delivered by TSE in a market control message. Once TSE has reported that order input is enabled,
client system can post financial transactions. Further market control messages are possible, which
indicate changes in the state of TSE system.
TSE protocol specifies two types of messages that can be posted by a virtual server to TSE relay
server. Those are transaction messages and instruction messages. Both kinds of messages are input
in a one-query-one-response mode. The two kinds of messages are independent and can be input in parallel.
One type of messages is specified by TSE protocol for output - those are referred to as notices.
Notices are also output in one-query-one-response mode.
Each type of messages mentioned above has a corresponding acknowledgement message: once an acknowledgement
is received, next message of corresponding type can be posted.
Orders can be blocked into batches of up to 20 blocks for transmission from virtual server. All types
of orders are allowed in one batch. Once put together, batch is send as a single upstream message.
Similarly, notices are received from TSE in batches of up to 10 blocks.
According to TSE protocol, each order is assigned one sequence number, each notice is assigned two
sequence numbers. Order sequence numbers are provided by client system; order sequence number of
succeeding order must be greater than order sequence number of preceding order. Gaps are allowed
in order sequence numbers.
TSE system introduces several types of notices, each type is assigned its own sequence numbers. Two
examples of notice types are order receipt/error notices and contract notices. Furthermore, each type
of notices is assigned two different sequence numbers: one is bound to member, the other is bound
to virtual server. Suppose one member has two virtual servers set up:
When a receipt notice is sent to either of these virtual servers, member-bound sequence number for
receipt notices is incremented. Also, virtual server-bound sequence number for receipt notices is
incremented for virtual server, which receives the notice. In case of contract notices mechanism
is the same. In the above case TSE system maintains the following notice sequences:
-
Member bound sequence for receipt/error notices (sequence number SEQNO_MREC)
-
Member bound sequence for contract notices (sequence number SEQNO_MCON)
-
Virtual server 24001 sequence for receipt/error notices (sequence number SEQNO_VS24001REC)
-
Virtual server 24001 sequence for contract notices (sequence number SEQNO_VS24001CON)
-
Virtual server 24002 sequence for receipt/error notices (sequence number SEQNO_VS24002REC)
-
Virtual server 24002 sequence for contract notices (sequence number SEQNO_VS24002CON)
TSE system provides its clients with recovery mechanisms. Member can request notices to be resent
or to be re-routed from one of its virtual servers to another. These facilities are provided by
TSE via mechanism of operating instructions.
When client code uses TSE Access Library, it operates with entities called sessions. In terms of C++,
a single session with TSE is represented by an object, which exposes a set of methods to control session
state, send TSE operating instructions and post financial transactions. As TSE provides responses to
posted commands and transactions, session object delivers those via a set of event notification callbacks.
The following UML diagram represents the core structure of TSE Access Library session object:
An important notice is to be made: no interface method invocation results in a synchronous callback!
Result of an operation is always provided as an interface method return value.Thus, client code is protected
from re-entries. On the contrary, a callback handler can safely invoke library interface methods.
Both exposed methods and delivered events form TSE Access Library interface, which is described in detail
in this section.
Communication between client and TSE system can be thought of as two-layer. Lower level has little
idea about financial information flow, its duties include:
-
Establishing and supporting TCP connection with TSE system(socket I/O operations)
-
Managing logical connection with TSE including message acknowledgements, sequence number
validation, performing log-on/log-off procedures.
-
Formatting and posting TSE operating instructions. A term "operating instruction" implies
one of the following: a resend request, a reroute request, a cancellation of either resend
or reroute request, or a sequence number query.
-
Packing transaction data blocks provided by client into transaction messages
and posting them to TSE in accordance with TSE protocol.
-
Notifying client of any session-related events: session establishment and termination, transaction
message acknowledgements, operating instruction acknowledgements and market state changes.
Low level operations are represented by ITSE_SessionControl interface. It is an abstract
C++ structure, which contains two data types and ten methods. The data types are:
-
ETSE_SessionControlReturnType - data type represents a set of possible return values for
ITSE_SessionControl interface methods. TSE Access Library uses non-blocking approach to all
socket operations, which has proved more efficient. As a result, some operations may return before
actual completion.eTSE_SessionControl_OK indicates successful completion, whileas
eTSE_SessionControl_InProgress means rather that operation has not failed immediately. Other
return values indicate errors: eTSE_SessionControl_OperationNotAllowed - requested operation is
not allowed in current library state; eTSE_SessionControl_DuplicateConnection - duplicate connection
attempt for a session object; eTSE_SessionControl_InvalidParameter - an invalid parameter was
passed in invocation; eTSE_SessionControl_QueueOverflow - a maximum of 20 transactions
already wait for posting/acknowledgement. eTSE_SessionControl_CommObjectError indicates that
operation has failed.
-
ETSE_SessionState - data type represents a set of possible session states. Initial state
for a session object is eTSE_Disconnected, eTSE_Connecting indicates that TCP connect
is in progress, eTSE_LoggingOn indicates that session object is waiting for a "Virtual server
Ready ACK" message from TSE, eTSE_WaitingFirstMCM is the state when session object is waiting
for market state information. After receiving a market control message, which indicates that order input,
is enabled, session object enters either eTSE_Online or eTSE_OnlineNoOI state, the latter
meaning that operating instructions are not allowed by TSE. Finally, during log-off procedure session object
is in eTSE_Disconnecting state.
Session control methods are:
-
ETSE_SessionState TSE_SessionState() const throw()
Method returns current session state.
-
ETSE_SessionControlReturnType TSE_EstablishSession() throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method initiates session establishment procedure. If TCP connect succeeds rightaway, method
returns eTSE_SessionControl_OK, in case of failure one of possible error codes is returned; if
error is not caused by duplicate connection attempt, session state is reset to eTSE_Disconnected.
-
ETSE_SessionControlReturnType TSE_EndSession() throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method initiates disconnection procedure. If disconnection can be completed rightaway, method will
return eTSE_SessionControl_OK, otherwise eTSE_SessionControl_InProgress will be returned
and client will be notified with via a callback when disconnection completes.
-
ETSE_SessionControlReturnType TSE_RequestResend(const char* _cszOriginalServer_ID,
const char* _cszNoticeType,
char _chSequenceNoType,
u_long _ulFirstSequenceNo,
u_long _ulLastSequenceNo) throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method formats and posts a request for TSE to resend all notices designated for virtual server with ID
_cszOriginalServer_ID, of type _cszNoticeType, sequence number type _chSequenceNoType
starting from sequence number _ulFirstSequenceNo up to sequence number _ulLastSequenceNo.
Virtual server ID must be a 5-byte zero-terminated string, notice type must be either "01"
for receipt/error notices or "02" for contracts notices, sequence number type must be
either '1' for member-bound sequence number or '2' for virtual server-bound
sequence number._ulLastSequenceNo can be zero, in that case TSE will retransmit all notices up
to the most recently posted. Return values indicate whether local operation has succeeded. If no notices
are to be resent, operating instruction is rejected by TSE. TSE reject notification is always delivered
as an asynchronous callback.
-
ETSE_SessionControlReturnType TSE_CancelResend() throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method terminates a currently active resend request. Return values indicate whether local operation has
succeeded. If no notice resend is in progress, operating instruction is rejected by TSE. TSE reject
notification is always delivered as an asynchronous callback.
-
ETSE_SessionControlReturnType TSE_RequestReroute(const char* _cszOriginalServer_ID) throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method formats and posts a request for TSE to reroute all notices designated for virtual server with ID
_cszOriginalServer_ID to virtual server that posts reroute request. Virtual server ID must be
a 5-byte zero-terminated string. Return values indicate whether local operation has succeeded. If
reroute request can't be satisfied, TSE reject notification is delivered as an asynchronous callback.
-
ETSE_SessionControlReturnType TSE_CancelReroute(const char* _cszOriginalServer_ID) throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method cancels any notice reroute in progress for virtual server _cszOriginalServer_ID. Virtual
server ID must be a 5-byte zero-terminated string. Return values indicate whether local operation
has succeeded. If current reroute can't be canceled, TSE reject notification is delivered as an
asynchronous callback.
-
ETSE_SessionControlReturnType TSE_RequestSequenceNo(const char* _cszServer_ID) throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method formats and posts a request for TSE to provide the most recent order sequence number accepted
from virtual server sending the request. Asynchronous TSE response contains sequence number itself
as well as the corresponding transaction message posted by client. Return values indicate whether local
operation has succeeded.
-
const STSESessionStatistics& TSE_GetSessionStatistics() const throw(IEventLogInterface::ELogStatus,std::bad_alloc)
This method returns session object statistics. Return type is a const reference to a structure
that contains information about current session, such as sequence numbers in both upstream and downstream
directions, system and product code for current session and space available in current order block.
This method has no error return value. When state of session object is eTSE_Disconnected, contents
of returned structure are undefined.
Invocations of methods listed above generally may result in response actions from TSE side. All TSE response
messages are translated by session object into C++ callbacks, which are brought together by notification
interface ITSE_SessionNotification. This interface is also represented by a C++ structure that contains
one data type and five event callback prototypes. Client code willing to receive session level notifications
needs to derive from ITSE_SessionNotification, implement its methods and provide session object with
implementation. Data type enclosed in ITSE_SessionNotification is described below:
-
ETSEDisconnectionReason - data type represents a set of possible reasons for session disconnection.
Except for user-requested disconnection, which may complete synchronously, any session disconnection is
reported as an asynchronous callback. Following reason codes may be encountered in disconnection callback:
eTSEDisconnectionReason_ConnectionFailed indicates that connection to TSE has failed asynchronously,
eTSEDisconnectionReason_DataParseError is returned when session is severed due to a corrupted message
from TSE, eTSEDisconnectionReason_DialogError is returned as a result of data flow error,
eTSEDisconnectionReason_MarketState is returned when TSE system reports offline state,
eTSEDisconnectionReason_EndOfDay is a result of an end-of-day sequence, eTSEDisconnectionReason_UpperLevelRequest
is a special code, which indicates a user-requested disconnection and is never delivered in a callback,
eTSEDisconnectionReason_BadSequenceNumber occurs when a bad sequence number is received from TSE,
eTSEDisconnectionReason_MemberErrorReceived is returned when TSE finds an error in a data message
posted by virtual server.
An application that makes use of TSE Access Library can potentially have more than one session established
with TSE system, hence, it needs to differentiate between session objects. A virtual server ID is by itself
enough to identify a session in the system, however, TSE Access Library provides an additional property for
session object, called "session ID" - an integer number assigned by client during session object construction.
Sesison ID is of type TTSESessionID, which is a typedef for C++ unsigned long. TSE Access Library
makes no use of this identifier, only provides it as the first parameter with every event callback for corresponding
session.
Event callback prototypes are described below:
-
void TSE_NotifySessionEstablished(const TTSESessionID& _refSessionID) throw()
Callback notifies user about the establishement of session with TSE. It is delivered to client when library
processes first market control message with TSE status "online". From that moment session object has enough
information to post transactions and operating instructions.
-
void TSE_NotifySessionClosed(const TTSESessionID& _refSessionID, ETSEDisconnectionReason _eReason) throw()
Callback notifies user about the termination of TSE session. Termination means that no TCP connection exists
with TSE relay server. Additional information is written by library code to log file (if provided). _eReason
contains reason code for disconnection.
-
void TSE_NotifyMarketControlMessage(const TTSESessionID& _refSessionID,
bool _bRealizingDataInput_ExcOptions,
bool _bOrderInput,
bool _bRealizingDataInput,
bool _bMarginStatus,
bool _bOperatingInstructionInput,
char _chSystemStatus,
bool _bSequenceNumbersSet,
u_long _ulOrderSeqNo_VS,
u_long _ulMessageSeqNo)
Callback notifies user that a market control message has arrived from TSE. Boolean parameters indicate
whether various operations are enabled on TSE system. false value indicates that TSE currently
does not allow corresponding operation. _chSystemStatus can have one of the following values:
'0' indicates that system is offline; '1' indicates that system is online
or has recovered; '3' indicates that system is suspended; '9' indicates that
system is down; space indicates a change in transaction status. _bSequenceNumbersSet
flag indicates whether this market control message brings valid sequence number information. If it is
set to true, _ulOrderSeqNo_VS contains the latest order sequence number received by TSE
from current virtual server. _ulMessageSeqNo contains sequence number of corresponding transaction
message (this type of sequence numbers is completely managed by library).
-
void TSE_NotifyOperatingInstructionACK(const TTSESessionID& _refSessionID,
u_char _chReasonCode,
const char* _cszOpInstrAckType,
u_long _ulSequenceNo = 0,
TSE::CFrameWrapper _fwTxMessage = TSE::CFrameWrapper())
Callback notifies user about the result of an operating instruction request posted before. _chReasonCode
contains completion result. '0' indicates success, any other value is an error code described
in TSE specification (constants for error codes can be found in TSE.hh/TSE.cc library files).
_cszOpInstrAckType contains type of operating instruction being acknowledged, _ulSequenceNo
and _fwTxMessage are only filled if operating instruction in question is a sequence number query
and operating instruction request has succeeded. In this case _ulSequenceNo contains sequence
number queried, _fwTxMessage wraps buffer that contains original transaction labeled with this
sequence number.
-
void TSE_NotifyInputACK(const TTSESessionID& _refSessionID,u_long _ulTxSeqNo,int _iReasonCode)
Callback notifies user that a previously input transaction has reached and was validated by TSE relay
server. _ulTxSeqNo is the original sequence number of input transaction, _iReasonCode contains
result of primary transaction validation by relay server. Zero value indicates success, any other value
should be interpreted as an error code described in TSE specification (constants for error codes can be
found in TSE.hh/TSE.cc library files).
Two interfaces described above give user all means to control a single TSE session and receive information
about session state transitions and session-level events. Rest of functionality, which includes formatting
and posting financial transactions and receiving TSE notices, is provided by the other two interfaces that
represent the upper level of TSE Access Library. Unlike previously described session-related interfaces,
these two are unaware of any session level details. Upper level handles the following tasks:
-
Providing means that allow easy access and formatting of TSE order and notice messages. Upper level
includes a set of classes that wrap all TSE protocol messages and provide easy way to access and check
consistency of message fields.
-
Delivering all notices arriving from TSE to client in the form of C++ classes. Delivery as a raw buffer
is also possible.
Transaction posting functionality is represented by ITSE_STSTradeControl interface. It is an abstract
C++ structure, which has two data types and seven methods. Data types are:
-
ETSE_STSTradeControlStatus - data type represents a set of return values for ITSE_STSTradeControl
interface methods. eTSE_STSTradeControl_OK indicates that a transaction was successfully accepted
by session object. eTSE_STSTradeControl_PostFailed indicates a general failure,
eTSE_STSTradeControl_OutOfSequence means that an operation that was attempted, was out of sequence,
eTSE_STSTradeControl_SessionDown indicates that an operation has failed due to session state;
eTSE_STSTradeControl_SystemError is returned in case of a system error inside the library and
is normally accompanied by an extended log message.
-
ETSE_STSTradeState - data type represents a set of possible states of transaction input. Values are:
eTSE_STSTrade_NoSession, eTSE_STSTrade_TransactionsDisabled and eTSE_STSTrade_TransactionsEnabled.
TSE Access Library's trading interface covers two different strategies of posting transactions. First one
gives implements a "query-one-post-one" algorithm, where user first requests an instance of desired input
message, then either fills it with data and posts it, or drops it, releasing resources. A subsequent input
message instance cannot be requested from the library without previous one being either posted or dropped.
Attempt to do so will cause an error return value of eTSE_STSTradeControl_OutOfSequence. Types that
represent input messages are part of library interface.
Second strategy implies that client code does all the routine concerning message formatting and provides
library method with a ready buffer. This strategy imposes no extra limitations on how many posts are done
in a row.
Taking the above into account, ITSE_STSTradeControl interface methods looks like the following:
-
TSESTS::COrder_New& TSE_STS_Request_Order_New() throw(ETSE_STSTradeControlStatus,IEventLogInterface::ELogStatus,std::bad_alloc)
Method returns a reference to an internally created object of type TSESTS::COrder_New, which
is a C++ wrapper class for TSE New Order message.
Returned reference should be used by client code to fill order with data, then either a post or a drop
method must be called before TSE_STS_Request_Order_New can be called again.
-
TSESTS::CCross_Order& TSE_STS_Request_Cross_Order() throw(ETSE_STSTradeControlStatus,IEventLogInterface::ELogStatus,std::bad_alloc)
Method returns a reference to an internally created object of type TSESTS::CCross_Order, which
is a C++ wrapper class for TSE Cross Order message. Semantics is same as for New Order.
-
TSESTS::COrder_Cancel& TSE_STS_Request_Order_Cancel() throw(ETSE_STSTradeControlStatus,IEventLogInterface::ELogStatus,std::bad_alloc)
Method returns a reference to an internally created object of type TSESTS::COrder_Cancel, which
is a C++ wrapper class for TSE Cancellation Order message. Semantics is same as for New Order.
-
TSESTS::COrder_Revision& TSE_STS_Request_Order_Revision() throw(ETSE_STSTradeControlStatus,IEventLogInterface::ELogStatus,std::bad_alloc)
Method returns a reference to an internally created object of type TSESTS::COrder_Revision, which
is a C++ wrapper class for TSE Revision Order message. Semantics is same as for New Order.
-
ETSE_STSTradeControlStatus TSE_STS_PostTransaction(unsigned long _ulTransactionSequenceNumber) throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method posts a transaction message that was previously created in a call to one of TSE_STS_Request_* methods.
If no transaction was created prior to calling TSE_STS_PostTransaction, return value
will be eTSE_STSTradeControl_OutOfSequence.
-
ETSE_STSTradeControlStatus TSE_STS_DropTransaction() throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method is used to discasrd a previously requested transaction. After calling this method another
transaction can be requested from the library. If no message was created prior to calling
TSE_STS_DropTransaction, return value will be eTSE_STSTradeControl_OutOfSequence.
In case of TSE_STS_DropTransaction such a return is not considered as an error.
-
ETSE_STSTradeControlStatus TSE_STS_PostForeignTransaction(unsigned long _ulTransactionSequenceNumber,
const char* _cszTXBuffer,
int _iTXLength) throw(IEventLogInterface::ELogStatus,std::bad_alloc)
This method is used for posting preformatted transactions. Calling this method does not affect the state
of any transactions requested from the library via TSE_STS_Request_* methods.
-
ETSE_STSTradeControlStatus TSE_STS_DeliverCollectedTransactions() throw(IEventLogInterface::ELogStatus,std::bad_alloc)
Method is used to deliver transactions queued inside session object immedieately. Method will fail if there
is a transaction that was posted but not yet ACKed by TSE. Otherwise, transactions that are queued and
waiting for delay timeout expiration will be packed and posted.
TSE Access Library delivers TSE notices to its client via ITSE_STSTradeNotification interface.
Client code derives from an abstract C++ structure, implements its methods and registers implementation
in session object in order to receive notifications. Basically, all callbacks are similar in that they
accept a session identifier, a reference to an object of a special type that represents TSE message
header and a reference to a particular notice object. Classes representing TSE notices provide access
and validation methods for all message fields. Notification interface is outlined below:
void TSE_STS_NotifyOrderStatus(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSE::CReceipt_Status& _refNotice)
void TSE_STS_NotifyCrossOrderStatus(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSE::CCross_Order_Receipt_Status& _refNotice)
bool TSE_STS_NotifyTSENotice(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const char* _cszFrameStart,
int _iFrameLength)
bool TSE_STS_NotifyOrderReceipt(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::COrder_Receipt_Notice& _refNotice)
bool TSE_STS_NotifyOrderError(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CNew_Order_Error_Notice& _refNotice)
bool TSE_STS_NotifyCrossOrderError(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CCross_Order_Error_Notice& _refNotice)
bool TSE_STS_NotifyCancelError(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CCancellation_Order_Error_Notice& _refNotice)
bool TSE_STS_NotifyAmendError(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CRevision_Order_Error_Notice& _refNotice)
bool TSE_STS_NotifyContract(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CContract_Notice& _refNotice)
bool TSE_STS_NotifyCancel_Revision(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CCancellation_Revision_Notice& _refNotice)
bool TSE_STS_NotifyEndOfNotices(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CEnd_Of_Receipt_Contract_Notice& _refNotice)
bool TSE_STS_NotifyExpiredOrder(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CExpired_Voided_Notice& _refNotice)
bool TSE_STS_NotifyRegistrationInvalidOrder(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CRegistration_Invalid_Order_Notice& _refNotice)
bool TSE_STS_NotifyRegistrationInvalidCrossOrder(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CRegistration_Invalid_Cross_Order_Notice& _refNotice)
bool TSE_STS_NotifyRegistrationInvalidCancelOrder(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CRegistration_Invalid_Cancel_Order_Notice& _refNotice)
bool TSE_STS_NotifyRegistrationInvalidReviseOrder(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CRegistration_Invalid_Revise_Order_Notice& _refNotice)
bool TSE_STS_NotifyStopOrderPriceInfo(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CStop_Order_Notice_Price_Information& _refNotice)
bool TSE_STS_NotifyStopOrderData(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::CStop_Order_Notice_Order_Data& _refNotice)
bool TSE_STS_NotifyOtherDataTypeErrorNotice(const TTSESessionID& _refSessionID,
const TSE::CHEADER& _refHeader,
const TSESTS::COthers_Data_Type_Error_Notice& _refNotice)
The only callback that deserves special attention is TSE_STS_NotifyTSENotice. It is always
invoked first, when a notice message arrives from TSE and it delivers raw notice buffer to the client.
Aside of the interfaces described above, session object provides initialization methods for user to register
callback interfaces and to query control and trade interfaces. Prototypes for those methods are given below:
-
ITSE_SessionControl* TSE_STS_GetControlInterface() throw()
-
ITSE_STSTradeControl* TSE_STS_GetTradeInterface() throw()
-
void TSE_STS_RegisterSessionClient(ITSE_SessionNotification* _pSNI) throw()
-
void TSE_STS_RegisterTradeClient(ITSE_STSTradeNotification* _pTNI) throw()
TSE system receives and transmits data over communication media using proprietary binary
format. TSE Access Library provides a convenient system of frame access classes capable of
frame parsing and composition. For each data entity, such as an Order block defined in TSE data
specification, a corresponding C++ class is defined. All data access classes have similar structure,
their code being being automatically generated, based on formal data specification.
Data formats utilized by TSE differ for different markets. TSE Access Library data framework follows
this separation defining every market's data access classes in corresponding separate namespaces.
However, since certain session-level messages, such as message header are common
for all markets, those are defined in common TSE:: namespace. Currently TSELib
defines two separate namespaces for data access: TSESTS::, covering Stocks trading and
TSEFOI:: for Futures, Options and Indices. Upcoming releases will include TSETST::
(ToSTNet) and TSEBTS:: (Bond Trading system).
Following UML diagram presents general picture of the data manipulation framework.
For simplicity only one data access class, namely COrder_New is displayed.
Raw frame manipulation
Class CFrameWrapper represents a raw memory buffer allocated somewhere. It does not
control buffer's allocation and release, instead it stores buffer pointer and length and
provides a set of methods for accessing underlying frame. CFrameWrapper's interface
is divided into two parts:
-
Frame Access Classes interface.
A frame access class like COrder_New has an associated CFrameWrapper class
instance. Frame parsing and composition methods access frame's data via this instance.
Basically all methods of the frame access class like set_Field or get_Field
are just thin inline functions, responsible for field's type and position within frame.
And all the complexity of data manipulation is concentrated in CFrameWrapper's
format access interface. On the above diagram corresponding member functions are collectively
called FormatAccessAlgorithms. Their primary aim is to provide sophisticated routines
for raw frame access to be called from particular fields code.
-
User side interface.
CFrameWrapper instances are normally created by user code and are used to attach Frame
Access class instances for subsequent field access. User side interface is thus comprised
of Frame Access class attach/detach functionality. Frame access objects can be attached
to the beginning or to the end of a CFrameWrapper object. The second parameter of
Attach method provides this option. Attach operation results in cutting a part from either
the beginning or the end of the controlled buffer and assigning just cut part to the instance of
frame access class. As soon as an instance of frame access class is attached, it can check underlying
frame's consistency, extract or store field values. Allocation of CFrameWrapper-controlled buffers
is left to user: it can be dynamic or automatic memory.
As explained above, all the complexity of data formats used in data specification is concentrated
in CFrameWrapper class. TSE system protocol has specific data formats such as prices
and quantities that require specific alignment and filling. For instance, price can be
either 'Market price', 'Limit price', or 'Unfilled'. On user side such field's
value is represented by an instance of CFrameWrapper::STSEPrice structure. Integer value fields
with similar characteristics are represented by CFrameWrapper::SUITWithStatus data type.
To summarize, CFrameWrapper class has very simple contents - a pointer to raw buffer and
its length. However, it contains sophisticated functionality for manipulating frame's content.
CFrameWrapper objects can be instantiated on arbitrary buffers and can be used
as a base for frame access classes, which can be attached to and detached from the designated frame.
Frame access classes
Frame access classes represent most valuable part of TSELib's data access framework. Their objective
is to simplify procedure of manipulating the content of raw character frames, understood by
TSE trading system. Any data block is naturally represented as sequence of fields, frame
access classes contain access methods for every individual field.
All Frame Access classes have common functionality, concentrated in the base class - CGenericBlock.
As explained in previous section all access classes can be attached to CFrameWrapper instance. This
functionality is implemented by CGenericBlock::Attach, CGenericBlock::Detach methods.
Also, every frame access class has a designated frame, assigned during attach operation. This frame
is stored in CGenericBlock::m_Frame member and is accessed by implementations of all
field access methods. CGenericBlock class also contains DynamicClone method for
polymorphic creation of frame access instances on the heap. This functionality is useful when instances are
stored in heterogeneous containers forming queues or more sophisticated data structures.
Similar to DynamicClone method of CGenericBlock, all frame access classes have
Clone() method, which is not polymorphic and returns created instance to the caller on the stack.
Every field of a data block has special check_() method, that should be executed to
check whether underlying data is properly formatted. However, individual check_() methods
are not normally called by library users. Instead there is single check() method that invokes
specific check_() method for every field in the message.
set_() methods are used to assign new values to corresponding fields. There can be several
set_() for a single field. Different methods accept different parameters. If the parameter of the
set_() method cannot be converted to valid value for the field, an exception is thrown.
get_() method is used to retrieve field's value. It does not accept any parameters
and returns converted value via stack. get_() should always be applied to properly formatted
field, i.e. underlying code assumes that corresponding field has been checked with individual or
generic check() method. This assumption allows simpler get_() method implementation,
that should provide better performance. If prior check() operation has not been performed
debug version of the library triggers runtime assertion to signal improper usage on early stage
of the software development. There can be several get_() methods with different names
to return different representations of the field's value.
As mentioned above, set_ and check_() methods can throw exceptions to signal improper
parameter or field's value. Thrown exception has type CBlockException, defined inside
frame access class. This class in inherited from global CFrameException class.
CFrameException has single member - m_eReason, identifying error code, describing
exceptional condition. By itself CBlockException class can be thrown from Attach() and
Detach() methods to signal operation error. For example frame access object cannot be properly
attached, because supplied frame is too small. In all other cases derived instance is thrown.
All CBlockException classes have a single member, identifying the field that caused the exception,
so that exception handler can report invalid field and reason for exception.
When a session object is instantiated, it requires that the following configuration parameters are
provided in constructor:
-
const TTSESessionID& _crefSessionID - an integer assigned by user to identify this session
object within application. Session object makes no use of this parameter - only returns it with
every event callback.
-
const char* _cszMemberID - member ID provided by TSE. Must be 5 digits.
-
const char* _cszVirtualServerID - virtual server ID provided by TSE, must be 5 digits.
-
const char* _cszVirtualTermID - virtual terminal ID, associated with virtual server. Provided
by TSE. Must be 4 digits.
-
const char* _cszReceipsBackupVSID - ID of virtual server that will receive backup receipt
notices. Must be an existing virtual server ID or set to 5 spaces.
-
const char* _cszContractsBackupVSID - ID of virtual server that will receive backup contract
notices. Must be an existing virtual server ID or set to 5 spaces.
-
unsigned int _uiOrderCollectionTime - TSE Access Library provides a configurable timeout, during
which it will collect orders before sending them to TSE. Send operation will be performed when either
timeout expires or there are 20 orders waiting to be sent to TSE. This parameter sets the timeout in
milliseconds.
-
const char* _cszLocalIP - local IP address to which connecting socket is bound. Assigned
by TSE. Must be a valid IP address in "xxx.xxx.xxx.xxx" representation.
-
unsigned short _usLocalPort - local TCP port to which connecting socket is bound. Assigned
by TSE. Must be a valid TCP port.
-
const char* _cszRelayServerIP - relay server IP address, provided by TSE. Must be a valid
IP address in "xxx.xxx.xxx.xxx" representation.
-
unsigned short _usRelayServerPort - relay server listening TCP port, provided by TSE.
Must be a valid TCP port.
-
IEventManagerInterface& _refEventManager - a reference to event manager interface.
-
IEventLogInterface* _pEventLog - a pointer to event logger interface. Optional parameter,
default value is NULL.
This section provides guidelines for efficient using TSE Access LIbrary in client code. It consists
of several points that should be kept in mind when using library.
Session object construction
A single session object is represented by an instance of CTSESTSImpl class. Session object
allows copy construction and assignment to enable its insertion into STL containers.
Note that in case of copying, a newly created copy gains control over session lifetime. In case of
assignment the object in the left side of the assignment operator gains control over session lifetime.
Invoking session control interface methods
User should always examine session state after a session control interface method failure. Some
methods, being improperly invoked, can cause session termination, it is user's responsibility
to handle such situations. When session is terminated, session object performs its total state reset.
Session statistics returned by interface method is not guaranteed to be any real for a disconnected
session object.
Posting transactions
TSE Access Library provides two ways to prepare order data and send it to TSE:
-
On-the-Fly method. This one is normally used when message is being composed just before
being sent to TSE. In this case message is being composed directly inside library's
outgoing buffer. This should provide the best performance. Here's the sequence of steps to be taken:
-
Acquire order data access object from the library, attached to the outgoing buffer using
trade control interface:
TSESTS::COrder_New& l_refNewOrder = ITSE_STSTradeControl::TSE_STS_Request_Order_New();
-
Fill acquired transaction using proper set_() methods. Use composite
check(); method to see if accidentally some field is forgotten to be filled.
If all fields are successfully filled, call method
ITSE_STSTradeControl::TSE_STS_PostTransaction() to commit this order for
transmission. If frame composition exception has been detected, method
ITSE_STSTradeControl::TSE_STS_DropTransaction() must be used to cancel transaction request
and release relevant library resources.
-
Delayed method. All frames are prepared on buffers allocated by user and are provided to
the library in raw form. This approach is suitable for applications keeping queues of orders
or for those receiving preformatted TSE messages from other applications.
This way requires following steps:
-
Decide where raw frames are allocated. Data access headers have special global constants
for every defined data block. These can be used for frame allocation just in
automatic memory.
For example for new order on stocks market, frame access block TSESTS::COrder_New and
length constant TSESTS::g_culOrder_New_Length are defined.
-
Instantiate CFrameWrapper class using allocated buffer and its length as constructor
parameters.
-
Instantiate frame access object (for our example it is TSESTS::COrder_New) and
link it to just allocated buffer using CFrameWrapper::Attach method.
-
Now frame access object is ready to render outgoing buffer. Use corresponding set_()
method to fill order block. Optional check() method may be used to check whether
there are fields forgotten to be filled.
-
When the frame is ready to be sent to TSE, use method
ITSE_STSTradeControl::TSE_STS_PostForeignTransaction to pass ready order data
to the library for subsequent transmission.
Note that once TSE_STS_PostTransaction or TSE_STS_PostForeignTransaction has succeeded,
transaction message is stored within internal data structure waiting to be posted. Depending on
library configuration, posting may take some time. If during this time a disconnection occurs,
all orders stored by library, but not posted yet are discarded. First market control message after
session recovery must be used to determine the latest order actually received by TSE system.
Notice processing
When library receives a notice message from TSE, it first invokes callback to deliver the whole buffer
to client. This callback has default implementation that just returns true. After that, notices
are extracted one by one and notice-specific callbacks of ITSE_STS_Trade_Notification interface are
invoked. If user only wants to receive the raw buffer, the first callback should be overridden and
its implementation should return false. Generally, once a notice callback has returned false,
subsequent notice extraction is not performed and notices remaining in the buffer are discarded. This
scenario may me used by applications which don't need to deal with separate notices and only have to
pass the whole buffer further on.
Current release of TSE Access Library has no specific software or hardware dependencies. Ordinary TCP/IP
stack is used for communications and is accessed via sockets interface. TSE Access Library can be built
on any system that has a standard-compliant C++ compiler and supports major POSIX system calls and
Berkeley Sockets interface to TCP protocol.
TSE Access Library requires that application's implementation of main loop supports a predefined interface.
Library is accompanied with an example of UNIX version of event manager that implements application's main
loop. Description of required interface can be found in this document.
TSE Access Library's objects will make use of an event logging component if one is provided during
construction. Event logging interface supported by library is described in
this document. Event categories supported by session objects are: all predefined categories,
"TSE raw data" (controls dumping of data being passed in hexadecimal format) and "TSE comm.debug" (additional
debugging information for communication level)
-
Library was developed and tested in Solaris 7, 8 operating environment using SUNPro 6U2 family
of compilers. Various gcc versions starting from 2.95.3 were used for source code conformance testing
and cross-compilation. Generally a release can be provided for any C++ standard compliant compiler, for
any platform that supports Sockets and a major subset of POSIX system calls, however, it may require
additional testing and possibly source code tweaking. TSE Access Library is initially provided as a
per-compiler static library, since some compilers fail to generate proper code for throwing exceptions
from dynamic libraries (ex: gcc). For compilers that guarantee safe exception throwing from dynamic
libraries shared binaries can be provided as well (shared binaries exist for Sun's SUNPro 6U2). Due to
different ABIs used by different C++ compilers, usage of shared libraries is restricted to dedicated
compilers.
-
_UNIX_APP_ preprocessor symbol should be defined before including library headers when using
the library under UNIX, since some of the accompanying headers use it to identify UNIX builds.
-
Library uses NDEBUG preprocessor symbol to differentiate between debug and release compilation modes.
Library is shipped with a sample application that highlights library features described in this document
and can be used as a test console for TSE Stocks Trading System. Application reads a configuration
file on startup and displays command prompt. User can create TSE sessions according to configuration file
entries, load order data, send multiple transactions and review state of existing sessions. Sample application
includes implementations of event manager and event logger, which conform to library's requirements.
If you're interested in this library, please contact us:
© Orchid Technology K.K. 2002 All rights reserved