Menu

Monday, November 15, 2010

HOWTO: Wrap Interactive Brokers TWS api in a Matlab class.

There are many ways of interfacing Matlab with Interactive Brokers API. The main choice is of course whether you are going to buy a commercial product (like quant2ib) or go the DIY route (a-la Max Dama). For me it was the second option. The reason is that not only am I short of $600 for an interface, but in most cases a commercial product will have some limitations compared to your own or open-source code.
I've started with the code from Max that really got me a flying start, but his approach to interfacing is far from optimal. One would need a bunch of global variables and separate functions to get the data back and forth. Synchronization to events also becomes very difficult with this approach. Without object oriented design, one would quickly become bogged down in 'spaghetti' code.
So I went another route: wrapping all of the tws stuff in a single class and using events for synchronization. This was not trivial to do, as passing class methods as a callback function proved quite tricky.  With code from leptokurtosis.com (thanks!) this issue was solved and I finally managed to create a descent wrapper.

Here is the base code for the wrapper : ib_matlab_tutorial.zip
It's a basic skeleton that can be extended further. At this moment only market data subscriptions  are implemented. To add order placing, historical data etc. you'll need to add some code, but from here on most of the heavy lifting is already done.

How to use:
- install tws ActiveX , enable api connection in tws
- start TWS
- open demoScript.m  and step through the code blocks to see what happens.

File description:
CTws - main wrapper class .
CSymbolData - used by CTws as a data container
CListener - basic example of a listener class, listening to tws events.
GenericIbEvent - used for passing symbol data within an event (written by leptokurtosis.com)
demoScript - basic tws/listener demo

Have fun!
Any remaks/improvements are welcome!

26 comments:

  1. Sjev,

    I'm glad this worked out for you.

    I just let people know about your improvements in a note: Improved Matlab-IB Interface

    Max

    ReplyDelete
  2. For some reasons it does not work for me... I'm new to OOP in Matlab, probably I do something wrong.

    When I run >> tws.subscribe('SPY')

    I got error message

    ??? Undefined variable "IB" or class "IB.CSymbolData".

    Error in ==> CTws>CTws.subscribe at 68
    obj.symbolData{iNewSubs} = IB.CSymbolData(symbol);

    Any suggestions?

    ReplyDelete
  3. Try renaming the 'ib_matlab_tutorial' dir in '+IB'. Your error is caused by missing 'IB' namespace. You could also delete all 'IB.' prefixes in the code.

    ReplyDelete
  4. Well, I got it working. I have deleted two "IB." from CTws.m. I'm not really sure what I've done but it works.

    Also I've extended list of variables for the contract to be able to get stock from different stock exchanges. However, there is still a problem if you have two different stocks with the same code. I think it could be better to use as parameter not just code but something like 'Exchange:Code'.

    Thanks a lot for the good work. Do you have any plans to add other stuff there - historical data and trading? I think I can not do it myself even having your files to work with.

    ReplyDelete
  5. Thank you, sjev. I've already deleted 'IB.' by shaking hands and without real understanding what I'm doing. I have to start learning OOP...

    ReplyDelete
  6. @timbo: I have no plans for adding the 'bells and whistles' as it would make it more difficult for others to understand the code. My own development of couse includes all the fancy stuff. I've had a thought on creating a commercial product but I don't think that the customer base would be broad enough to justify the efforts. And competition with quant2ib would not make it better.

    ReplyDelete
  7. Too bad :-(
    For me the code looks already difficult and that leaves me very little chance to make all necessary stuff.
    Anyway, thanks a lot for what you've done and shared here.

    ReplyDelete
  8. Hi Sjev,

    Just wondering where I should place the code to capture capture the incoming ticks?

    Inside the CListner there is an event handler, "handleEvent" event which prints out the incoming tick to the command window.

    I tried grabbing the tick and writing it to a vector but because its inside the event its seems that I'm not in the same context as as the declared vector.

    I tried declaring the vector as global but still didn't work.

    Any suggestions?

    Thanks,

    Chris

    And thanks again for sharing this code. I was very helpful. (I too don't have the 600 for Matlab2IB)

    ReplyDelete
  9. @Chris: you should make this vector a class property, that is public or protected. Take a look at the Matlab documentation on OO programming, it will make it all clear.

    ReplyDelete
  10. Hi Sjev,

    The main issue seems to be trying to interface 64-bit Matlab to TWS via a 32-bit OCX control.

    Any ideas of how to overcome that issue?

    Thanks,

    Jonathan

    ReplyDelete
  11. @Jonathan: maybe this will help: http://www.interactivebrokers.com/php/apiUsersGuide/apiguide/activex/running_the_activex_api_on_64-bit_windows_xp_systems.htm

    ReplyDelete
  12. Hello Jonathan, you can't use 32 bit
    ocx,dll or com in 64 bit app.

    sjev: this is about using 32 bit api under 64 bit windows.

    under my own affair:
    TWSLink, which can be downloaded and tested 14 days for free here

    http://www.trade-commander.com/twslink/twslink_en.htm

    enbales complete IB API 9.63 for MatLab 32 bit.
    It is fast, efficient, powerful and reliable.
    In addition you can use it with many other applications (32 bit) or programming languages.

    ReplyDelete
  13. Hi Sjev,

    I'm new to quant world and have just started to get my feet wet.

    I was hoping you could check out the two links below, and see if there is something in that code that you might use? I'm a noob, and thus have no clue, but if the codes in refining your own code, that would be awesome

    Thanks

    http://www.trade-strategy.com/code.php?project=InteractiveBrokers&file=IBexamples


    http://www.trade-strategy.com/code.php?project=InteractiveBrokers&file=IBevent

    ReplyDelete
  14. Does anybody know how to save this prices and times whilst listening?

    ReplyDelete
  15. Sjev,

    I'm new to OOP. I tried your code, but at the very beginning (line 9 of demoScript.m,
    tws = CTws;)
    I got the following error message:


    ??? Error using ==> feval
    Input PROGID does not represent an Activex control.
    If this PROGID used to work before, please check vendor's
    documentation for equivalent activex control progid.

    Error in ==> C:\Program Files\MATLAB\R2010b\toolbox\matlab\winfun\actxcontrol.p>actxcontrol/createControl at
    208


    Error in ==> C:\Program Files\MATLAB\R2010b\toolbox\matlab\winfun\actxcontrol.p>actxcontrol at 179


    Error in ==> CTws>CTws.CTws at 35
    obj.tws = actxcontrol('TWS.TwsCtrl.1',[0 0 0 0],obj.f);



    Would you please give some suggestion on what's going on and how to solve it. (I am using R2010b)

    ReplyDelete
  16. @uhome: you probably did not install IB activex component correctly, or you have a 64 bit system.

    ReplyDelete
  17. I have a Window 7 64-bit system. So do I need some adjustment? or I just can't use it?

    ReplyDelete
  18. @sjev

    I get the same error as uhome but am running Windows 7 32 bit. I'm pretty sure I have TWS activex installed correctly - one just uses the regular installer right? Any ideas from your geniusness?

    Kind regards,
    Trevor

    ReplyDelete
  19. I was thinking of going with the DIY (active x) route for this but was impressed with what I found at
    http://undocumentedmatlab.com/ib-matlab/

    BTW - I'm totally new to this and just got the product last week...

    There's a lot of great documentation, the guy keeps the code updated and it supports live streaming data where the data will be updated even if matlab is in the middle of running a function (I think that's the idea)... Check it out and it's also not as expensive as the other java wrapper.

    Also, for those that work with the IB API... check out
    http://finance.groups.yahoo.com/group/TWSAPI/

    Regards,
    Ben

    ReplyDelete
  20. @jev,

    Do you know how I can get your code working I'm using Windows 7 64bit and get the same error as @uhome. I can't get hold of Max anymore plus he's taken off his original code.

    would really appreciate your guidance jev.

    thxs
    Dian

    ReplyDelete
    Replies
    1. I have seen on the IB site that the latest release of activeX api should support 64bit systems. Have not tested it though.

      Delete
  21. I like a lot of what you did, my rendition is much more 'spaghetti'-like. Why is it that the twsevent function will not capture the continuous tickPrice feed?


    ReplyDelete
  22. hi sjev
    I'm trying to execute line tws.connect and below error come up.
    Error using COM.TWS_TwsCtrl_1/connect
    Error: Type mismatch, argument 4

    Error in CTws/connect (line 41)
    obj.tws.connect('', 7496, 101);

    do you know what cause this type mismatch? i have enabled activeX api in tws.

    thanks

    ReplyDelete
    Replies
    1. Same here. I am on 32bit Win7

      Delete
    2. Sorry, can't help you with that. I've abandoned Matlab 3 years ago.

      Delete