3

I am trying to learn about this API and there is a detail that is confusing me a lot. I am not used to work with classes and interfaces and I don't understand one detail.

In this API there are two classes that are very important: EClient and EWrapper. EClient is used to place orders and send requests. EWrapper is used to process the messages received from the API.

In all books, websites, tutorials... they create a new class that inherits those two classes. What I don't understand is the code used in the init function is different in the different sources. How is this possible?

Let me show what I mean.

Source 1, their videos on Youtube, this is how they create a new class (TestApp) that inherits the EClient and EWrapper classes:

https://www.youtube.com/watch?v=dzOilFBDmJI&list=PL71vNXrERKUpPreMb3z1WGx6fOTCzMaH1&index=4

from ibapi.client import EClient
from ibapi.wrapper import EWrapper

class TestApp (EClient, EWrapper):
    def __init__ (self): 
        EClient.__init__(self, self)

I have two questions about this:

1 Why are they using self two times? (self, self)

2 Why is that they don't use EWrapper init function?

Something like this:

EWrapper.__init__(self, self)

Source 2, a book "Algorithmic Trading with Interactive Brokers (Python and C++)".

Here is how the create the new class:


class SubmitOrder (EClient, EWrapper):
    def __init__ (self, addr, port, clientId):
        EWrapper.__init__(self)
        EClient.__init__(self, self)

I have 2 questions:

3 Why is that here they call the EWrapper init function?

4 Why is that there are two self (self, self) for EClient and one self (self) for EWrapper.

Source 3, their very own documentation:

https://interactivebrokers.github.io/tws-api/client_wrapper.html

First they say you have to implement the EWrapper interface with this code:


class TestWrapper(wrapper.EWrapper):

But after the : there is nothing, so here is my question.

5 What code should I use to implement the EWrapper interface? They talk about interfaces instead of classes. I have read an interface is similar to a class but defined methods are abstract, you are suposed to override the methods. I understand that you don't override methods in EClient but you have to with EWrappper. But I have no idea on how to "Implement the EWrapper interface". Unfortunately their code looks incomplete in the very first step of something that should be in every programm.

After that, they explain you have to create an EClient class, and you have to use the EWrapper here so you can receive messages:


class TestClient(EClient):
    def __init__(self, wrapper):
        EClient.__init__(self, wrapper)

Here are my question:

6 Why do they use wrapper instead of EWrapper? As far as I know wrapper is the file where the EWrapper class is stored.

Finally they use TestWrapper and TestClient to create the new class. Here is their code:


class TestApp(TestWrapper, TestClient):
    def __init__(self):
        TestWrapper.__init__(self)
        TestClient.__init__(self, wrapper=self)

Here are my questions:

7 Why is that some init functions have one self, and others two?

I see here that the second "self" in the TestClient is equal to the wrapper. And that makes some sense because of their explanation:

"To use EClientSocket, first it may be necessary to implement the IBApi.EWrapper interface as part of its constructor parameters so that the application can handle all returned messages. Messages sent from TWS as a response to function calls in IBApi.EClientSocket require a EWrapper implementation so they can processed to meet the needs of the API client."

This shows the second self is equal to wrapper, and that makes me remember code from Source 1:


EClient.__init__(self, self)

The second self is not equal to wrapper, so this is my last question:

8 How can this code work without explicitly equaling self to wrapper?

As you can see I am super lost with this, hopefully someone could explain a little bit this.

Thanks for your time.

2 Answers2

3

Keep in mind I don't use python except to show IB examples here on SO... I may be wrong.

Note, class TestApp (EClient, EWrapper): means TestApp inherits from both Eclient and EWrapper. Or, your client for sending messages to TWS and your wrapper for receiving messages are both the TestApp class.

EClient.__init__(self, self) 1 Why are they using self two times? (self, self)

The first argument in a class is always self to represent itself, jsut the way python works. The second argument is because python expects an argument for the EClient init method. This argument is the wrapper for data callbacks.

2 Why is that they don't use EWrapper init function?

It does nothing. I f you look at the source it's just a bunch of methods meant to be overridden. It has a default implementation of just logging. More of what I'd call an interface.

3 Why is that here they call the EWrapper init function?

Maybe just programming style, it does nothing.

4 Why is that there are two self (self, self) for EClient and one self (self) for EWrapper.

Ewrapper takes no arguments so it's just passing the self that's used in all python classes.

5 What code should I use to implement the EWrapper interface?

There are 2 classes, EClient is used to call TWS\IBG and then TWS will usually call IB's servers and the reply will come back to you in some way. The only way for TWS to know where to send the reply is to tell it by specifying the wrapper in the init method.

So if you want to see data you override those data callbacks in your wrapper (called TestApp or SubmitOrder in these examples so far). It's simple just look at some examples I'll show later, but basically just copy a method from the EWrapper class and change it to what you want.

6 Why do they use wrapper instead of EWrapper?

class TestWrapper(wrapper.EWrapper):

In the above they would have done from ibapi import wrapper so there is no EWrapper imported, just a different way of doing import.

class TestClient(EClient):
    def __init__(self, wrapper):
        EClient.__init__(self, wrapper)

In the above note that wrapper is an argument name passed to init and re-sent to the EClient init, they can call it whatever they want but IMO this is bad practice to reuse names.

  1. answered in 1.
TestClient.__init__(self, wrapper=self)

Note above means they made a TestClient subclass of EClient already and in TestApp they are initializing it using the named argument wrapper=self. You can send arguments by name or position, so here it serves more to remind you of what the argument is for.

The second self is not equal to wrapper, so this is my last question:

8 How can this code work without explicitly equaling self to wrapper?

Remember in the first code TestApp is a subclass of both EClient and EWrapper, so self is indeed the wrapper. It is also the client.

Here is an example that doesn't use multiple inheritance and shows some overridden methods. https://stackoverflow.com/a/54423878/2855515

brian
  • 10,619
  • 4
  • 21
  • 79
0

This is by no means full answer, but here is __init__ of Eclient class.

class EClient(object):
    (DISCONNECTED, CONNECTING, CONNECTED, REDIRECT) = range(4)

    #TODO: support redirect !!

    def __init__(self, wrapper):
        self.msg_queue = queue.Queue()
        self.wrapper = wrapper
        self.decoder = None
        self.reset()

Then to answer your question about two selfs: the first one is just how python works (indication that this is non-static method), and the second one is for the wrapper, but since we inherit from both classes (one of them Ewrapper) we use self (for wrapper). The object that we instantiate is itself a wrapper.

user1700890
  • 7,144
  • 18
  • 87
  • 183