softwarespartan / IB4m

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

Market data lag #92

Open dakr001 opened 4 years ago

dakr001 commented 4 years ago

Dear @softwarespartan , @Despair200,

I'm experiencing significant lag when requesting market data events.

I'm simply using a callback function to print to screen as ask/bid price events arrive. After printing to screen I apply a 5 second lag to simulate some other calculations that I need to do. After 5-10 minutes, the price displayed through the event data is lagging the bar chart by several minutes.

I used the market data event itself as well as the current market data buffer. Both are outdated. I get the buffer from the base workspace using evalin.

Do yo have any hints?

Below is my code if it is helpful.

Thank you very much.

` [market_databuf,marketdataListener] = TWS.initBufferForEvent(TWS.Events.MARKETDATA,1000);

contract = com.ib.client.Contract(); contract.symbol('AUD'); contract.secType('CASH'); contract.exchange('IDEALPRO'); contract.conid(14433401);

listener_marketdata = event.listener(... TWS.Events.getInstance ,... TWS.Events.MARKETDATA ,... @(s,e)process_marketdata(e.event) ... );

function process_marketdata(e)

if e.data.tickId==1 | e.data.tickId==2 market_databuf = evalin('base', 'market_databuf'); mktDataEvents = collection2cell(market_databuf); response = market_databuf.get(); disp(datetime('now')) disp(['Market data events: ' num2str(numel(mktDataEvents))]) disp(['Direct e data: ' char(e.data)]) disp(['Buffer data (get): ' char(response.data)]) disp(['First data in buffer: ' char(mktDataEvents{1}.data)]) gotbid=false; gotask=false; for ix = numel(mktDataEvents): -1 : 1 e2 = mktDataEvents{ix}; if e2.data.tickId==1 & ~gotbid gotbid=true; disp(['Last data in buffer (bid): ' char(e2.data)]) end

if e2.data.tickId==2 & ~gotask
    gotask=true;
    disp(['Last data in buffer (ask): ' char(e2.data)])
end   

if gotbid & gotask
    break
end

end

`

purchagent commented 4 years ago

the pause(5) is probably the issue I use a buffer for certain things like account update where there is a mix of data. For the prices, I enter them into an empty array function onDataEvent(this,evt)
if evt.data.tickId==4 this.prices(this.loc,1)=evt.data.value; this.loc=this.loc+1; end and then grab the last entry My results are pretty good. I did find last week though that my prices for the open/close are sometimes off enough where I needed to make a change. Instead of reqMktData, I am looking at reqTickbyTickData like bondtrade asked about in issue #89 Yesterday I decided to update my price right before my entry. I will see on Monday how much that improves the precision.

That is an impressive amount of calculations you are doing to take 5 seconds Could you use a timer that after 5 seconds runs the second portion? That way you can keep the data input separate

When you say outdated, do you mean the api version? https://www1.interactivebrokers.com/en/index.php?f=24356#976

dakr001 commented 4 years ago

@purchagent Thanks for your comments.

My understanding is the data buffer, which is in the base workspace, is continually updated regardless of the 5 second delay.

[market_databuf,marketdataListener] = TWS.initBufferForEvent(TWS.Events.MARKETDATA,1000);

Given that you update the prices in the callback function, how do you pass this array to other functions/scripts that might require them?

The 5 second is a long story :) Basically IB doesn't allow me to trade certain instruments in my country so I have to get Matlab to interact with another order entry platform...

I meant the price is outdated, compared to what I see in the bar chart.

softwarespartan commented 4 years ago

Would strongly discourage putting any pause in your codes. Event processing is not procedural. Events are processed on an internal java event thread. If you put this thread to sleep, all event processing will halt. In general you should use 5 second bars (reqRealTimeBars). Unless you're a Jedi Matlab coder, Matlab code is not fast enough to keep up with market data events. The problem only gets worse if use TickByTick data. Also, you should just get the latest event from the buffer directly. Doing things like collection2cell at every real time market event is extremely expensive.

dakr001 commented 4 years ago

@softwarespartan Thank you.

I put the 5 second pause here to simplify the code. The actual code does some other calcs. Does this mean that I can't use the callback function if there is some significant amount of calculation involved after getting the event? In my example, I'm updating orders as the price events come in. However the update takes time because Matlab has to interact with other software.

I tried using get, but still noticed lag in the data: response = market_databuf.get();