Direct trade entry in Tradebase and removal of JdbcLog

3 messages Options
Embed this post
Permalink
toli

Direct trade entry in Tradebase and removal of JdbcLog

Reply Threaded More More options
Print post
Permalink
Hey there,

We've had added slight architectural change in the past week which has
to do with how OMS and Tradebase interact, and how trades are being
added and recorded in Tradebase.

In the "old" model (what's shipping and available for download now)
the OMS would record the incoming FIX Execution Reports in the
database, and then one would have to go into Tradebase and go to
Trades -> Import Trades to add all the new trades to Tradebase.

But that's "2 clicks", you'd say! "2 clicks is slower than none!".
And you'd be right - which is why we listened, filed and implemented
RFE 455 (http://trac.marketcetera.org/trac.fcgi/ticket/455 ) to enable
automatic import of trades into Tradebase. If we had a major marketing
department, we'd call it "Marketcetera No-Click Trade Recording (TM)"
(thankfully, we don't).

So there you have it - automatic trade recording from OMS into
Tradebase. If you'd like more details on the implementation, read on.

To tell you the truth, I never liked the initial approach of using
JdbcLog to record incoming execution reports - you needed to create
non-OMS related DB tables, it relied on Proxool (connection pooling)
which occasionally misbehaved, it coupled the OMS with non-OMS related
logic too much, and I always saw a specter of my old Stanford CS prof
telling me it was bad design.

The new approach is much slicker (or so we think). We decoupled OMS
from trade recording altogether - the OMS now just forwards the
incoming execution reports to another JMS queue, which (if it's setup)
is being picked up by the Tradebase using the ActiveMessaging
(http://code.google.com/p/activemessaging/wiki/ActiveMessaging)
plugin.  This way, people only using the OMS don't have to deal with
the database hit, and Tradebase users get automatic trade recording.

On the Tradebase side, you need to run the "poller" script to setup
JMS polling, and it automatically finds and registers all the JMS
processors. The next release of the appliance will have this system
built-in, so it'll be working out of the box.

Naturally, this allows you to have your own JMS listeners to subscribe
to these execution report messages as well, and makes integration that
much easier.

We'll keep the JdbcLog and necessary dependencies around for those who
choose to persist all the incoming messages into the DB, but as of
next release that will be an optional configuration.

Let me know if you have any questions, and would love to hear your
thoughts on this. If you want to see the code, the OMS changeset is at
http://trac.marketcetera.org/trac.fcgi/changeset/1564 and the
Tradebase at http://trac.marketcetera.org/trac.fcgi/changeset/1561 .

Happy Trading

--
Toli Kuznets
http://www.marketcetera.com: Open-Source Trading Platform
download.run.trade.
_______________________________________________
m-etc-users mailing list
[hidden email]
http://lists.marketcetera.org/cgi-bin/mailman/listinfo/m-etc-users
dumitriu

Re: Direct trade entry in Tradebase and removal of JdbcLog

Reply Threaded More More options
Print post
Permalink
Hi Toli,

This looks like a great change.  I just have a couple of comments.

After having glanced at the code, it seems to me that the execution report should be sent to the trade recorder topic regardless of whether or not it is sent to the client(s).  In other words, why is

if(FIXMessageUtil.isExecutionReport(message)) {
                    char ordStatus = message.getChar(OrdStatus.FIELD);
                    if((ordStatus == OrdStatus.FILLED) || (ordStatus == OrdStatus.PARTIALLY_FILLED)) {
                        logMessage(message, session);
                    }
                }

nested inside the following code block?

        if (jmsOperations != null){
            try {
                jmsOperations.convertAndSend(message);
                if (message.getHeader().isSetField(DeliverToCompID.FIELD)) {
                    // Support OpenFIX certification - we reject all DeliverToCompID since we don't redilever
                    Message reject = fixMessageFactory.createSessionReject(message, SessionRejectReason.COMPID_PROBLEM);
                    reject.setString(Text.FIELD,
                            OMSMessageKey.ERROR_DELIVER_TO_COMP_ID_NOT_HANDLED.getLocalizedMessage(message.getHeader().getString(DeliverToCompID.FIELD)));
                    quickFIXSender.sendToTarget(reject);
                    return;
                }

                if(FIXMessageUtil.isExecutionReport(message)) {
                    char ordStatus = message.getChar(OrdStatus.FIELD);
                    if((ordStatus == OrdStatus.FILLED) || (ordStatus == OrdStatus.PARTIALLY_FILLED)) {
                        logMessage(message, session);
                    }
                }

            } catch (Exception ex) {
                LoggerAdapter.error(OMSMessageKey.ERROR_SENDING_JMS_MESSAGE.getLocalizedMessage(ex.toString()), ex, this);
                if(LoggerAdapter.isDebugEnabled(this)) { LoggerAdapter.debug("reason for above exception: "+ex, ex, this); }
            }
        }


Also, as I mentioned in a previous post, in order to support returning status to certain clients on separate topics, some kind of mapping from outgoing order id to queue name should be maintained, so that incoming status messages can be sent to the appropriate place.

Currently the code is structured so that all outgoing messages (to the broker/exchange) go through OutgoingMessageHandler and all incoming messages (from the broker/exchange) come through QuickFIXApplication.  Really these two classes would need some shared data structure, e.g. Map<ClOrdID, Destination>, to keep such a mapping.  OutgoingMessageHandler.handleMessage could grab the ClOrdID and map that to the JMS Message.getReplyTo(), for example. Unfortunately, the use of Spring's MessageListenerAdapter class hides the JMS message from OutgoingMessageHandler so it can't get the replyTo.  QuickFIXApplication.fromApp() could then lookup the appropriate destination using the incoming FIX message ClOrdID.

Just my 2 cents.  What do you think?

Cheers,
Dan
toli

Re: Direct trade entry in Tradebase and removal of JdbcLog

Reply Threaded More More options
Print post
Permalink
Dan,

> After having glanced at the code, it seems to me that the execution report
> should be sent to the trade recorder topic regardless of whether or not it
> is sent to the client(s).  In other words, why is

You are right - the two should be decoupled. It seemed "inconceivable"
that someone may want to not have a topic for all incoming FIX
messages, but that's obviously wrong :)

I've modified the code and added tests for this behaviour in
http://trac.marketcetera.org/trac.fcgi/changeset/1568 .

>
> Also, as I mentioned in a previous post, in order to support returning
> status to certain clients on separate topics, some kind of mapping from
> outgoing order id to queue name should be maintained, so that incoming
> status messages can be sent to the appropriate place.

You are right here as well - there's no easy way to 'demultiplex' the
incoming FIX messages across different reply topics. I've created an
RFE to track this: http://trac.marketcetera.org/trac.fcgi/ticket/458

thanks for your feedback!

--
Toli Kuznets
http://www.marketcetera.com: Open-Source Trading Platform
download.run.trade.
_______________________________________________
m-etc-users mailing list
[hidden email]
http://lists.marketcetera.org/cgi-bin/mailman/listinfo/m-etc-users