IB API for C++

Discussion in 'Automated Trading' started by KPS21, Sep 4, 2006.

  1. KPS21


    The documentation on the IB website makes it seem like you can only use their C++ API with Microsoft Dev Studio.

    Does anyone happen to know if this is true? Or is it possible to use, for instance, GNU C++ instead?

  2. Yeah, it will. Here's the README. See number 5).
    C language API for TWS workstation clients
    (released under GPL and Artistic license)

    1) Introduction

    The C API tracks Unix/Mac releases even though they are updated less frequently
    because the newest beta releases are sometimes unreliable.
    This API implements client functionality version 23.
    It has been tested against TWS server version 23.
    It is released as is, without warranty of any kind.
    Be advised that it may contain bugs and I can't be held responsible
    for any trading losses you incur as a result of them.
    It is my hope that by releasing this implementation to the public we'll
    let each other know about bugs and get rid of them.

    2) How to use
    This API has been tested on linux, solaris and windows and is trivial to port
    to other unix OS's if it doesn't compile error free.
    Generally speaking any POSIX compliant OS ought to be able to compile and
    run this API.

    a) include "twsapi.h"

    b) implement callbacks of interest in callbacks.c

    c) write a thread starter routine according to the documentation of your thread
    library which will be used to start the event loop that drives the callbacks.
    See mythread_starter() example routine in example.c.

    d) create 1 or more tws client instances and match callbacks to
    instances by setting the unique variable "opaque" in tws_create().
    That variable will be echoed in every callback.
    Note: in response to several queries I should point out that "opaque" can be used
    to disambiguate several instances of tws or to share state between requestor and
    callback routine.

    e) Link in your code
    On windows one might do:

    cl -MDd -DWINVER=0x400 -DWINDOWS -nologo -W3 -Yd -Zi -c twsapi.c callbacks.c
    cl -MDd twsapi.o callbacks.o $(YOUR_OBJECTS) -FeEXECYUTABLE_NAME.exe ws2_32.lib

    if using visual studio, or if you prefer the mingw compiler then

    gcc -DWINDOWS -D_REENTRANT -Wall -g -c twsapi.c callbacks.c
    gcc twsapi.o callbacks.o $(YOUR_OBJECTS) -o EXECUTABLE_NAME.exe -lws2_32

    Be sure to define -DWINDOWS for windows. BTW WIN32 is a bad name used almost
    everywhere because people forget that there is 64 bit windows and processors other
    than x86.

    On linux one might do:
    $(CC) -D_REENTRANT -Wall -g -c twsapi.c callbacks.c
    $(CC) twsapi.o callbacks.o $(YOUR_OBJECTS) -o a.out -lpthread

    Example: link twsapi.o and callbacks.o with example.c and run it.

    f) If there are any problems recompile code with -DDEBUG to see the output of more printfs.

    3) Motivation
    The currently available APIs from Interactive Brokers do not offer a lightweight,
    high performance library to link with. The Java runtime is a veritable performance hog
    and the C++ API doesn't care about performance either by gratuitously making use of
    exceptions and windowisms like MFC CString classes.
    Either way the total memory footprint of the IB APIs is unnecessarily large.
    Additionally if someone wants to do interprocedural optimizations he needs the source code.

    4) Rationale for this implementation and some programming notes

    Theoretically strings that are exchanged between the TWS client and server may
    have unlimited size, however, by using sufficiently large char arrays in the
    twsapi.c implementation (512 bytes for each string), the possibility of decoding
    errors is practically obviated (for IB bulletin messages only the size is set to 127*512 bytes).
    Large switch statements are used instead of jump tables to give the compiler
    discretion how to optimize best.
    String allocation and deallocation happen via fixed size bitmaps and as a result
    they are fast and can never lead to memory fragmentation.
    Take note that all functions in the API use the standard C calling convention,
    which might be a problem if a thread has to be started that uses the Pascal calling
    convention. Wrap calls to Pascal routines in C routines to avoid stack leaks.
    Style notes: lowercase literals, optionally separated by _ are used throughout
    to conform to BSD/linux kernel coding conventions.

    5) C++ users
    To use this API with C++ rename callbacks.c to callbacks.cpp and bracket entire set of functions
    with extern "C" { at the top and } at the bottom of the file. The callbacks may be implemented with
    C++ objects freely. Be sure to compile C files with a C compiler and C++ files with a C++ compiler because
    modern C++ compilers are unforgiving when it comes to certain valid C constructs.

    Please direct bug reports to snikolov@tanika.net or file them on sourceforge.net.
  3. Another good example of OpenSource development done by guys who know what they'r doing (and why). Clean, fast and robust, unlike the "well it works doesn't it" toy's we're getting used to in the Windoze world. This opens up for professional use.

  4. KPS21


    Thanks for the info.

  5. Here, this might help someone linking C libraries into C++. See your compiler's docs for any specifics or possible deviations.

    Alternate linkage specifications
    What happens if you’re writing a program in C++ and you want to use a C library? If you make the C function declaration,

    float f(int a, char b);

    the C++ compiler will decorate this name to something like _f_int_char to support function overloading (and type-safe linkage). However, the C compiler that compiled your C library has most definitely not decorated the name, so its internal name will be _f. Thus, the linker will not be able to resolve your C++ calls to f( ).

    The escape mechanism provided in C++ is the alternate linkage specification, which was produced in the language by overloading the extern keyword. The extern is followed by a string that specifies the linkage you want for the declaration, followed by the declaration:

    extern "C" float f(int a, char b);

    This tells the compiler to give C linkage to f( ) so that the compiler doesn’t decorate the name. The only two types of linkage specifications supported by the standard are “C” and “C++,” but compiler vendors have the option of supporting other languages in the same way.

    If you have a group of declarations with alternate linkage, put them inside braces, like this:

    extern "C" {
    float f(int a, char b);
    double d(int a, char b);

    Or, for a header file,

    extern "C" {
    #include "Myheader.h"

    Most C++ compiler vendors handle the alternate linkage specifications inside their header files that work with both C and C++, so you don’t have to worry about it.