iklan header

Using swigibpy so that Python will play nicely with Interactive Brokers API

The interactive brokers API is as far I realize the handiest way that a non institutional client can get admission to economic markets in a manner which makes properly programmatic, fully bendy, fully automatic trading feasible.

(I am ignoring broker supplied 'front ends' that may allow you to automate trades, and some Janet and John environments that provide the ability to implement algorithms in weird proprietary languages  for a limited number of instruments)

This is a good factor.

Now for the not so top things. Firstly the API will best run in Excel, Visual Basic Active X, Java, C , and C#. That is a piece like shopping for gasoline on your vehicle that will best paintings if you have a toy automobile, an electric powered toy automobile, a BMW or certainly one of two kinds of Land Rover, one in all that's only pushed in Iceland. There is no aid for the 'wimpy-quants' languages of preference, R, Matlab and Python.

NOTE:

There is now a local python API for interactive brokers. An up to date model of this post the use of the local API may be observed here.

(You can of route use something like Ninja Trader as a the front stop, however in case you're reading this you're now not that plenty of a wimp are you?)

The true news is there are things like IbPy andswigibpy available to help us Python customers, with my choice of swigibpy (see the December 2013 publish for why). A brief Google exhibits the life of comparable applications for R and Matlab. This mainly sit between your more excessive level language and the C API.

Secondly the documentation isn't always incredible, either for the IB API itself or swigibpy. So it takes pretty a lot of fiddling round and trial and errors to get things running. There are some constrained examples out there at the internet for example right here is one of the exceptional for IBpy; however they commonly cover the absolute fundamentals and consciousness on buying and selling person equities. They may be additionally very a great deal of the 'like right here is some code, and it appears to paintings' with none clarification that might assist you to apprehend and undertake the code in your personal functions.

Because I am a pleasant man and a public servant in addition I intend on this and subsequent posts to provide enough working documentation to get you up and walking with an interface to IB that you may use as a place to begin to build an automatic buying and selling device in python. This will also be of use to those the use of IB API in different non swigibpy environments.

(Assumptions: I am the use of Python 2.7.4; older or newer variations may additionally break. I will anticipate you realize your manner around Python to the extent of being capable of create a simple package deal and modules and run them. My command line examples will be for Linux but comparable matters need to be feasible. Also which you recognize the dangers and dangers of buying and selling futures; however you will need to sign a whole lot of disclaimers before IB allow you to do that for actual so I will allow them to worry approximately that.)

Getting a take a look at account, downloading the IB TWS

To play with IB without signing up for real you will need a test account. By the way if you are serious and you get a real IB account you can also request an additional account for simulated trading.

(The test account isn't always very realistic, eg fees may be total rubbish. The simulated account is a good deal higher despite the fact that for some cause you don't usually get L1 and L2 records to all the records feeds your actual account is signed as much as. If you will do any systematic trading within the near destiny I especially suggest signing as much as IB and using a proper simulated account. It doesn't price some thing in case you don't exchange or use any additional statistics feeds.)

We aren't going to trouble downloading the TWS software program, that is a rather heavy front stop beneficial for trading yourself; but the tons lighter and greater solid 'Gateway'.

(I advise you to additionally download the TWS API sooner or later to have a play, but I don't recommend it for everyday going for walks of a strategy since it appears to be very risky due to the first-rate lardy weight of fancy ultra bloated GUI that it has to assist.)

  1.  Go to https://www.interactivebrokers.co.uk/en/main.php
  2. Click on trading menu, API solutions
  3. Under IB API click on more info
  4.  Click on IB gateway software
  5. Under UNIX clicks on IB gateway for Unix
  6. Follow the instructions.
The last section of the instructions asks you to type some gobbledygook to run 'TWS' (they mean gateway). Don't be a fool and create a shell script that does it for you. Then you just have to type something like . runGateway. I have a similar script for TWS.

  1. Select IB API radio button
  2.  Under username put 'edemo' and under byskipword put 'demouser'.
If all goes well you will eventually see a screen with a green bar showing a connected status at the top. This program acts as a server to byskip on your instructions from the API connection to the great IB server, wherever that is. You now need to configure your API to accept connections.

  1. Click on the Configure menu. Go to API settings
  2. Socket port - should be 4001.
  3. Trusted IP addresses - should include 127.0.0.1. If it doesn't you will need to add it.
  4. Read only API - you can leave this checked for now but when you come to submit trades should be unchecked.
  5. Go to precautions. You might want to suppress market cap warnings here when you start trading in earnest.
  6. Go to presets. Again check you are happy with the limits shown.
Unlike TWS the gateway is automatically set up to accept connections so this is all you need to do.

(There is not anything unique approximately 4001 so that you can alternate it however make certain to recall the range and best use a noticeably different range if you recognise you might smash Linux in the process. Checkhttp://en.Wikipedia.Org/wiki/List_of_TCP_and_UDP_port_numbers and make sure your recreation of Microsoft Ants isn't always running. I run or more Gateways in parallel each connecting to live and take a look at accounts. I partner a distinctive socket (I use 4001 as much as about 4005) with every account and gateway consultation.

127.0.0.1 is just 'this system'. If your code is running at the same machine because the Gateway you're high-quality. Otherwise eg in case you are on a network you'll ought to encombyskip the IP cope with of every other machines that might connect to the Gateway.)

You may want to peruse the reliable IB API manual. The extra interesting component is the C phase. I find it very beneficial if I am having problem snoozing.

Downloading required python libraries

swigibpy

Remember swigibpy is the way that python gets to talk to the c++ API for IB. Go to this page and follow the download instructions. Either method shown works for me.

(This might fail on a lacking Python.H record if you have too minimal a Linux build. Just do sudo apt -get install python-dev when you have the identical problem. )

Let's write a few code - k shall we get a few code I've already written

Pull the supply from here. The files of hobby are test1_IB.Py and wrapper.Py.

Running the instance

Once you have got the two documents above into a package deal you can just run test1_IB. If it really works properly you ought to see some thing like this:

Getting the time...

1395845174

So we now seem to have obtained a totally complicated manner of telling unix time!

Also I seem to have dedicated the lethal sin of 'like right here is some code, and it appears to paintings' with none explanation. So we could dig into this a piece greater.

All you wanted to know approximately IB connections but frankly could not care much less

Callback = IBWrapper()

    consumer=IBclient(callback)

elegance IBclient(object):

    def __init__(self, callback):

        tws = EPosixClientSocket(callback)

        (host, port, clientid)=return_IB_connection_info()

<snip - code missing here>

def return_IB_connection_info():

    """

    Returns the tuple host, port, clientID required through eConnect

    """

    host=""

    port=4001

    clientid=999

    go back (host, port, clientid)

(Pedantic point - Although the code says tws here, it in reality means gateway. Actually the customer doesn't understand or care what is on the opposite give up of the connection.)

As I said above you may have any number of IB servers (gateway or TWS session) going for walks; so I use a feature to tell me what host, port and clientid to apply when connecting (here the function is as an alternative stupid). As in short alluded to above each IB server will concentrate out for customers on a specific port (so those should be precise to the server). You also can have numerous clients connecting to the identical server. For example I even have one customer selecting up prices; another receiving accounting facts, some other coping with orders, numerous one off customers getting diagnostic records and one doing the washing up.

If a clientid is already in use with the aid of a linked session then IB will cry. It would not appear to be viable to kill a connection with out the python code terminating; there's a technique tws.EDisconnect() however the use of it makes no distinction, nor does putting tws=None or certainly some thing else quick of finding the thread strolling the python and killing it.

What this means when you have a sequence of features you will name in a given python session, all of which connect to TWS, you can not do something like this:

def main_function():

        functiona()

        functionb()

    def functiona():

        Callback = IBWrapper()

        consumer=IBclient(callback)

        purchaser.Do_something()

    def functionb():

Callback = IBWrapper()

        consumer=IBclient(callback)

        purchaser.Do_something_else()

... As the call to functionb will fail probably with blunders 509. Instead you need to do some thing like this:

def main_function():        Callback = IBWrapper()

        consumer=IBclient(callback)

        functiona(client)

        functionb(purchaser)

    def functiona(consumer):

        purchaser.Do_something()

    def functionb(purchaser):

        purchaser.Do_something_else()

Back to the story.

Callback = IBWrapper()

consumer=IBclient(callback)

elegance IBclient(object):

    def __init__(self, callback):

        tws = EPosixClientSocket(callback)

        (host, port, clientid)=return_IB_connection_info()

        tws.EConnect(host, port, clientid)

        self.Tws=tws

self.Cb=callback

<snip - code missing here>

The callback instance of IBWrapper is the beast which we should write to deal with messages getting back from the server; more of that during a 2d.

We should create the connection item as an instance of EPosixClientSocket initialising it with a callback characteristic. We then name the eConnect function so that our tws object is a completely fledged connection. If that appears like Outer Mongolian to you, don't worry. You shouldn't ever need to mess with these things. The factor is as soon as we have our client item (example of IBclient) we can make it do cool matters, like tell the time.

Telling the time - the difficult manner

We now call the speaking clock method of the IBclient:

print client.Speaking_clock()

### what number of seconds before we surrender

MAX_WAIT=30

<snip - code missing here>

elegance IBclient(object):

<snip - code missing here>

def speaking_clock(self):

        print "Getting the time... "

        self.Tws.ReqCurrentTime()

        start_time=time.Time()

        self.Cb.Init_error()

        self.Cb.Init_time()

        iserror=False

        not_finished=True

        at the same time as not_finished and not iserror:

            not_finished=self.Cb.Data_the_time_now_is is None

            iserror=self.Cb.Flag_iserror

            if (time.time() - start_time) > MAX_WAIT:

                not_finished=False

            if iserror:

                not_finished=False

        if iserror:

            print "Error took place"

            print self.Cb.Error_msg

        go back self.Cb.Data_the_time_now_is

tws.ReqCurrentTime() is an instance of a chic class EClientSocket features, from the authentic IB API guide. These are the features that ask the server to reflect onconsideration on doing something.

Things that are thrilling here #1: the wait loop

The issue we have here is that the IB API is very much set up as an event driven process. So not like normal sequential code like function A calling function B and function A returning the answer back. No instead we have function A just kind of hanging around waiting for function B and then somehow by magic function B just happens.

That is not the way I do stuff. I don't have to - I am running fairly slow trading systems not intraday high frequency stuff that needs to react to every tick for which an event driven system makes sense. Also it goes against my ethical beliefs. Why should function A have to wait for function B to run? What makes function B so special? Its just rudeness.

(Also I've never found debugging event pushed code to be especially smooth .... )

So what we need to do is make the consumer-server relationship seem sequential, at the least to some thing sitting outdoor the wrapper module. That also method we want to handle the situations of the issue now not completing in a reasonable time and completing with an errors.

Things that are thrilling here #2: The contents of self.Cb

All the things we are pulling out of self.cb (which is the callback we byskiped in when we initialised the IBclient object) set somewhere else as if by magic. Actually they get set when the IB server summons the callback, calling the appropriate method. In the official IB API manual these are the very classy Class EWrapper Functions.

There are 3 varieties of elegant ClassE Wrapper features / strategies:

Pointless methods that do not do anything

magnificence IBWrapper(EWrapper):

    """

Callback item handed to TWS, these capabilities can be referred to as immediately

    by way of TWS.

    """

<snip - code missing here>

    def nextValidId(self, orderId):

        byskip

    def managedAccounts(self, openOrderEnd):

        byskip

These methods are there because the IB server isn't always very gracious about now not being able to name sure strategies, and they do not get inherited from EWrapper (why not?!?! Sure why bloody no longer?!). When you start doing greater interesting stuff you'll find you might want greater of these; you'll begin seeing errors like this (which you may reproduce with the aid of getting rid of the managedAccounts approach):

NotImplementedError: SWIG director natural virtual method called EWrapper::managedAccounts

Method that manage errors

magnificence IBWrapper(EWrapper):

    """

Callback item handed to TWS, these capabilities can be referred to as immediately

    by way of TWS.

    """

def init_error(self):

        setattr(self, "flag_iserror", False)

        setattr(self, "error_msg", "")

    def blunders(self, id, errorCode, errorString):

        """

        error managing, simple for now

        Here are some common IB mistakes

        INFO: 2107, 2106

        WARNING 326 - can not connect as already related

        CRITICAL: 502, 504 can not hook up with TWS.

            Two hundred no safety definition discovered

            162 no trades

        """

        ## Any mistakes now not in this list we simply treat as statistics

        ERRORS_TO_TRIGGER=[201, 103, 502, 504, 509, 200, 162, 420, 2105, 1100, 478, 201, 399]

        if errorCode in ERRORS_TO_TRIGGER:

            errormsg="IB mistakes id %d errorcode %d string %s" %(id, errorCode, errorString)

            print errormsg

            setattr(self, "flag_iserror", True)

            setattr(self, "error_msg", True)

        ## Wrapper capabilities do not need to go back anything

<snip - code missing here>

Note the two distinctive techniques; init_error is just my personal method to ensure the callback has somewhere to keep the mistake. Wheras blunders() is remitted by using the IB API - if you took it out or renamed it the aspect could ruin.

You want to have at the least the 2 stages of error managing as shown here when you consider that a lot of the IB "mistakes" are without a doubt simply IB telling you its alive; kind of like a infant whining you need so as to recognise while to ignore them. Once you get severe you could even want to have a third level of errors for when things actually get nasty.

The way we handle errors is to make our waiting process finish before its proper finishing time with an error flag set. Subtle point; if an error appears when no process is waiting does anyone hear it? If a tree falls in an empty forest... does a bear crap on it? Well we'll still print the error.... arguably if there is no process to fail I wouldn't care.... for example if we temporarily lost the internet connection because, just suppose as a completely arbitrary example, you had builders in the house and they tripped the fusebox for the 5th time that morning... but if we weren't waiting for a price at the time I wouldn't be that bothered. Well I'd be livid with the builders but I wouldn't want the python client-server code to throw its toys out of the pram so I had to restart it.

That is one purpose why I don't boost an exception right here however let the calling manner do it.

Methods that honestly do something vaguely beneficial

Of which we only have two here; again one which is my init_ method, and the other is the IB mandated version:

def init_time(self):

        setattr(self, "data_the_time_now_is", None)

def currentTime(self, time_from_server):

        setattr(self, "data_the_time_now_is", time_from_server)

So we could reiterate what takes place right here.

<In the client function>

def speaking_clock(self):

        print "Getting the time... "

        self.Tws.ReqCurrentTime()

        start_time=time.Time()

        self.Cb.Init_error()

        self.Cb.Init_time()

<in the IBWrapper function, of which IBclient self.cb is an instance>

def init_time(self):

        setattr(self, "data_the_time_now_is", None)

<back in the client function speaking_clock>

        iserror=False

        not_finished=True

        at the same time as not_finished and not iserror:

<at some point in this while loop, in the IBWrapper function, of which IBclient self.cb is an instance this will get called at some point ... hopefully.... >

def currentTime(self, time_from_server):

        setattr(self, "data_the_time_now_is", time_from_server)

<and back in the client function speaking_clock, in the while loop>

not_finished=self.Cb.Data_the_time_now_is is None

            iserror=self.Cb.Flag_iserror

            if (time.time() - start_time) > MAX_WAIT:

                not_finished=False

            if iserror:

                not_finished=False         if iserror:

            print "Error took place"

            print self.Cb.Error_msg

        go back self.Cb.Data_the_time_now_is

We set data_the_time_now within the callback to just accept a fee after which ask the server tws.ReqCurrentTime(); then somewhere within the ether the IBWrapper example method currentTime gets referred to as by the server with the parameter time_from_server; we exchange the price of data_the_time_now within the callback example, and this terminates the loop. All this assumes we don't get an errors situation, or the server falls asleep and the process hits its MAX_WAIT. Pretty a lot the entirety else we do with the IB API is a variation on this particular theme so if that makes feel, you're now an expert.

(Note that the parameter names in the EWrapper technique feature definitions do not need to match those in the guide; within the manual it uses time that's already the call of an imported module.)

And We Are Done

Although this situation is quite simple, like the writer, it does illustrate most of the 'gotchas' from operating with swigibpy / Python / IB API. Subsequent posts will extend on this case to cover the entire lifecycle of getting a fee, producing an order, getting a fill, locating out what positions we've and operating out whether or not we have made sufficient money to buy a respectable pc.

This is the primary in a series of posts. The next submit is:

http://qoppac.Blogspot.Co.United kingdom/2014/04/getting-prices-out-of-ib-api-with.Html

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel