softwarespartan / IB4m

Interactive Brokers API for Matlab
GNU General Public License v2.0
62 stars 21 forks source link

Subscriptions - How to? #47

Closed Despair2000 closed 5 years ago

Despair2000 commented 5 years ago

As I understood it should be possible to subscribe to for example account updates and in this way receive continue updates on the portfolio. I wonder how this can be done. Right now I request an account update in every iteration of my main loop. Meaning I request the updates by issuing:

session.eClientSocket.reqAccountUpdates(true,account);

And at the end of the function I cancel the subscription again with:

session.eClientSocket.reqAccountUpdates(false,account);

Nicer would be of course to subscribe once and then only check the buffer in every iteration if there was an update or not. And this is were I'm unsure how to do it. Will there automatically come new updates to my buffer if I don't cancel the subscription and if so how do I handle the buffer. Can I somehow clear the buffer after I have retrieved an update (if so how?) and then can just use buffer.isEmpty to see if something new has come?

I assume similar should be possible with execution details, account summary and last but surely not least market data?

Despair2000 commented 5 years ago

OK, I made some progress here. but.clear clears the buffer (buf.remove seems to have the same effect though). Then I can see in the log of the gateway that indeed if I don't cancel the subscription (I tried it with an account summary) the API sends an update of the data every 3 minutes. But (here comes the problem) this update does not show up in my freshly cleared buffer as I would want to. What am I doing wrong?

Despair2000 commented 5 years ago

...also without clearing the buffer the events don't accumulate in the buffer. I need some help here. :-P

Despair2000 commented 5 years ago

Anybody?

softwarespartan commented 5 years ago

There are three events published around account "updates"

TWS.Events.TIME TWS.Events.ACCOUNTUPDATE TWS.Events.PORTFOLIOUPDATE

When I go through the AcountUpdate.m in the docs folder, no issue clearing buffer and then waiting a few minutes for more updates. I tried this a few times and no problem encounter. Can you confirm?

Despair2000 commented 5 years ago

Indeed, I can confirm. So I have to request account updates and not an account summary to receive the continuous updates. Very good. Thank you! With this new knowledge I will see if I can make this work also for market data. It is possible to subscribe to say 20 symbols at the same time and receive updates for their price data continuously, isn't it? If I get stuck I will probably bother you again. Thank you for your patience!

softwarespartan commented 5 years ago

No problem -- happy to help.

RE: working with market data for multiple symbols. Yes, you can simply use

TWS.initMarketDataBufferWithReqId(bufsz,reqid)

to create a buffer that only receives data for specific request ID. It's not the most efficient since you will have 1 event listener for each subscription. This means that for 20 mktdat subscriptions you'll have to do 20 checks per event so that each callback can "decide" if wants to enqueue the event. All but one of the callbacks will reject the event.

If need to scale to many data streams, check out

TWS.MarketData.EventHandler

which uses appropriate data structures to maximize event processing efficiency

Despair2000 commented 5 years ago

Thank you! I will look into this and probably come back with new questions. ;-)

Despair2000 commented 5 years ago

I implemented now subscriptions for the account, the portfolio and market data and all seems to work as it should. Just one more question. Is there somewhere a list with all the events one can subscribe to and the invoking functions?

softwarespartan commented 5 years ago

Hm ... not sure exactly what you mean

In IB4m, TWS.Events defines all events.

When instantiate instance of TWS.Session (i.e. getInstance()) a callback is configured to display TWS.Events.ERROR in the Command Window and a buffer is configured for TWS.Events.NOTIFICATION which is a circular buffer for any/all events.

You can access session event buffer at TWS.Session.eventBuffer

You can, of course, create your own listeners and callbacks as well for TWS.Events.NOTIFICATION.

Despair2000 commented 5 years ago

I expressed myself badly I assume. Now I found in the Events.m file a list with properties. I think this is what I was looking for. But for example the Executiondetails event. I can't find a method to cancel the subscription like there is for the account updates or market data. Does this mean that this event only is fired once after I called reqExecutions or will inte update but hasn't to be canceled?

softwarespartan commented 5 years ago

AFAIK, execution details are always generated when order is filled. You can request (on demand) to retrieve previous execution details from current TWS session by making an API call (i.e. reqExecutions)

So again, execution details are always provided by TWS. You just have to create a listener for them. This is different for events like portfolio updates etc that you have to explicitly ask TWS to start generating those events AND then create a listener for events.

See also: IB4m/docs/ExecutionDetailsExample.m and API docs

Despair2000 commented 5 years ago

Ok, understood. Thank you again for clarifying this! I close this issue now.