Invoking the Interactive Brokers API from Ruby
I released ib_ruby_proxy
, a service for invoking Interactive Brokers (IB) API from Ruby. You can read more about how it works on its README.
I had a lot of fun working on this one. It started with needing to interact with IB from a Ruby thing I have been building. There is an excellent option in Ruby called ib-ruby
. Based on the low-level socket API used by official implementations, it is a pure Ruby solution without external dependencies but, for the same reason, it is a bit brittle. Due to this and other factors, including this being a very crucial dependency for me, made me think in building an alternative.
My first idea was using JRuby and invoking the API directly. It worked well but JRuby startup time ruins the feedback loop for me. Having to wait 5 seconds whenever I ran a test removed a big chunk of my developer happiness. On top of that, I wasn’t entirely happy having to abandon MRI.
Then I thought of running a JRuby-powered service any Ruby process could communicate with. I analyzed a few alternatives and decided to go with DRb, which is part of Ruby standard library. The IB API works asynchronously: first, the client invokes a method and, then, one or more callbacks are received with the response data for the original request.
DRb makes invoking remote methods very easy, and it supports observable remote objects. This was great because it fits perfectly with the way the IB API works.
I did some quick performance analysis of DRb and observed that DRb is fast enough to dispatch 10,000 requests per second. This was more than enough for my purposes. Even the most liquid security at peak hours will trigger less than 100 ticks per second, and that is the most data-intensive operation I can think of.
A final thought: JRuby feels like magic, and I can’t imagine the kind of sorcery its team has done to create it. It is a modern Ruby that can interact seamlessly with Java. I was able to do funny things like introspecting Java classes and generating methods dynamically with Ruby. Also, I was able to extend existing Java classes with Ruby as if they were regular Ruby classes. All the things I tried just worked. Big kudos to JRuby team!
Recently I saw this article about TruffleRuby and its amazing startup time improvements. I haven’t played with TruffleRuby but if they manage to run Ruby on a JVM with an MRI-comparable startup time that would be a terrific addition to the Ruby scene.