Think Outside the Box

I came upon an interesting problem late last week.

I’ve recently implemented an OTR Bond interface to Calypso so that, when new TIBCO messages alerts us of a new “On-the-run” Bond issue, we can insert the appropriate data into Calypso. Of course, if it’s a new Bond, there’s also a good chance that we don’t yet have the Bond definition in Calypso and, for that, we use the Bloomberg Connect API to retrieve the Bond and link it to the Calypso BondBenchmark… Sorry. That was just an overview but I can already see that most of y’all have your eyes all glazed over. Didn’t mean to bore you to death.

Anyway, I’m rather familiar with Calypso’s Bloomberg Connect API and how it works. Puh-lease… give me a hard one!!! After all, I pretty much wrote the whole thing single-handedly a couple of years ago. Let’s just say that a request file is generated, then FTP’ed over to Bloomberg. Then, it’s your responsibility to poll the remote directory for the equivalent response file. Once it is available, you download it and parse it locally with the data you requested. Pretty straightforward, right?

Well, when I implemented the Bloomberg interface, I thought of the “requested” scenario and never bothered (foolish me!) to think outside the box. Let’s say you request a Bond with CUSIP 123456, then I’d simply generate a request file called cy_123456.req (cy being short for Calypso. Y’see? To top it all off Bloomberg states that there’s a maximum number of characters in the file name. Some puny amount like 12 or 15, I think.) So anyway, cy_123456.req would get processed and FTP’ed to the remote directory. Then, I’d poll every once in a while for a file called cy_123456.out. When the file would be present, I’d FTP it back to my local directory and remove the file remotely, thus cleaning up after myself.

This ain’t rocket science, right? That should work just fine, no?

If you’ve got one instance of Bloomberg Connect running, it runs fine and dandy, yes… but here at Countrywide, we got a bunch of environments all running in parallel. We’ve got a couple of development boxes, UAT, and of course, the production environment. The configuration for these boxes are identical and the OTR Bond adapter task kicks off from 4 AM until 5:30 AM. So now you have these 5 or 6 processes all running on different boxes each listening to TIBCO. Let’s say at 4:05 TIBCO broadcasts: The 3 month OTR Bond has CUSIP 2223123. Well what’s been happening is this: these processes would check Calypso and determine it that Gosh-darn-it… we ain’t got that Bond definition. Let’s go fetch it!

5 processes on 5 different machines each generating a request file, cy_2223123.req. Some time passes and the Bloomberg Engine running on each box processes the file and uploads it to the remote (COMMON!) Bloomberg directory. Some time later, these 5 processes would each look for some file, cy_2223123.out, download it back locally and proceed to delete the remote file.

Hmmm…. can I get semaphores implemented on top of FTP? On second thought, don’t answer that…

I’m surprised that the process failed so infrequently, but occasionally, you’d have some poor process who’d never get its .out file. No wonder, some selfish sibling would have wiped it out before he got a chance to retrieve it. The funny thing is that, had I even pondered the question back at Calypso, it would have easily been apparent. I just never bothered to think: “Hey, wait… what if they run this process 5 times instead of just once, which seems logical.”

The quick fix? We’ve decided, until Calypso issues an official fix, to stagger the execution time for OTR Processing. Typically TIBCO will broadcast OTR information sometime between 3 and 4 AM and, of course, that information remains cached for new subscribers. So as long as we don’t connect before 4 AM and we have each box start processing OTR Bond messages on TIBCO at 10 minute interval, each instance of Bloomberg Engine should, hopefully, get to do its thing by itself. It’s not the most elegant solution, but hopefully it’ll do the trick!

On-the-run Bonds

For the last few weeks, I’ve worked on implementing OTR Bonds in Calypso. An OTR Treasury security is the most recently auctioned Treasury bill, note or bond of a stated maturity, with OTR an abbreviation for “On-the-Run.” Today, 09/29/2006, for instance, the 3 Month OTR Bond has CUSIP 912795YL9 and was issued yesterday with a maturity of 12/28/2006. In 15 days, however, it will roll to a different Bond issued sometime in mid-October. So, in essence, the 3 month OTR Bond is a reference to an actual bond. Calypso’s modeled this quite nicely, in fact, with the concept of a Bond Benchmark which, itself, is an instrument that can be priced or traded, but actually references a “benchmark” Bond. Simply put, OTR securities provide a convenient way to model market data curves for Fixed Income Trading.

The thing that’s been rather tricky, actually, is to interface Calypso with a Treasury TIBCO feed that supplies us with the latest OTR Bond aliases. Obviously enough, the first step is to retrieve the Bond Benchmark to make sure that OTR Bond and the actual benchmark match the data provided by TIBCO. If they don’t match, then the Bond Benchmark needs to be updated as well. Then, however, we also need to update Calypso’s feed config so it knows how to retrieve the latest quote from TIBCO in the future.

It’s actually not all that complicated, except that the persistence layer for Calypo’s Bond Benchmark keeps barfing up NullPointerExceptions. Apparently it tries to do some caching, but it’s really not all that good at it, and considering that you’re dealing with… hell, let’s say one thousand bond benchmarks, Calypso’d be better off just fetching the data from the DB instead of spewing exceptions at me. That’s simply not polite.

Unfortunately, Calypso doesn’t give you the ability to trade a Bond Benchmark. You can trade the underlying Bond, but apparently trading a reference was too hairy to design. It’s true that it adds a level of complexity since you would need to take a “snapshot” of the benchmark at the point in time when the trade is created. If that trade settles a month down the line, the 3 month OTR Bond will have changed, but obviously the Bond which was traded will not! Then again, seeing it from that perspective, it might be just a little too confusing to keep track of. A nifty feature, though, would be to at least be able to enter a trade with the 3 month OTR Bond and having Calypso automatically fetch and populate the trade entry screen with the appropriate bond.

I’m kind of curious why not create a generic ProductPointer that can be traded and have the BondBenchmark either extend the base class or implement the interface. My gut says I’d go with an abstract base class since you’d want to bring down as much functionality as possible into the superclass and just give hooks to customize the behavior.

Have a good weekend,

Bloomberg, SWIFT, and other dinosaurs

Why are some of the most widely used protocols and data streams on Wall Street so antiquated? I’ve been working recently to interface my employer’s product with Bloomberg security data. FTP? Flat-file format? Errrr… I’m surprised they didn’t ask me to use punch cards to send my request via US Mail.

Now my first thought was that our client (on whose behalf I’m implementing this interface) is too cheap to get an upgrade on its Bloomberg License. Still, that doesn’t really make sense when upgrading to real-time quotes and reference data updates would have a significant upside for its traders.

No… I think this is all Bloomberg’s doing. They’ve got antiquated software that’s clearly (as far as I could discern from the API documentation) running batch jobs to query their data feeds and… well, you know… concurrency is, like, really hard. 😉 Then again, it could simply be that, like Microsoft and other pseudo-monopolies out there, Bloomberg knows he’s got the best data on the street and his clients will do just about anything to get to it. Clearly, if indices, quotes and credit events were drugs, Bloomberg would be the Pablo Escobar of the digital age.