softwarespartan / IB4m

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

Will a single HashSet in a HistoricalData buffer only contain data from a single eClientSocket.reqHistoricalData request? #58

Open ecpgieicg opened 4 years ago

ecpgieicg commented 4 years ago

Hi Abel,

As always, thank you for the package and also for helping the community here.

Will a single HashSet in a HistoricalData buffer only contain data from a single eClientSocket.reqHistoricalData request? In other words, if I make multiple historical data requests -- with different reqIDs, in a way that IB server does not throw errors -- do I need to check something else in order to re-group the returns?

softwarespartan commented 4 years ago

I guess Im not sure what errors you're referencing? Each item in the buf has reqId associated with it so easy to know which is which even with single buffer. Not sure the HashSet would be helpful here. You can use the function TWS.initMarketDataBufferWithReqId

ecpgieicg commented 4 years ago

For example, let's say 3 historical data requests are made.

>> javaaddpath(fullfile(pwd,'Jar','TWS973.jar'));
>> session = TWS.Session.getInstance();
>> session.eClientSocket.eConnect('127.0.0.1',7497,2);
>> [buf,lh] = TWS.initBufferForEvent(TWS.Events.CONTRACTDETAILS);
>> contract = com.ib.client.Contract();
>> contract.symbol("AMD");contract.secType("OPT");contract.exchange("SMART");contract.currency("USD");contract.lastTradeDateOrContractMonth("20190816");contract.strike(34);contract.right("Call");
>> session.eClientSocket.reqContractDetails(0,contract); pause(0.5);
>> contract.conid(buf.get().data.iterator().next().contractDetails.conid)
>> [buf,lh] = TWS.initBufferForEvent(TWS.Events.HISTORICALDATA);
>> session.eClientSocket.reqHistoricalData(105,contract,'20190713 16:00:00','1 W','1 min','TRADES',1,1,false,[]); pause(0.5);
>> session.eClientSocket.reqHistoricalData(106,contract,'20190713 16:00:00','1 D','1 min','BID',1,1,false,[]); pause(0.5);
>> session.eClientSocket.reqHistoricalData(102,contract,'20190713 16:00:00','1 W','3 mins','TRADES',1,1,false,[]); pause(0.5);
>> iter=buf.iterator();

Can we know for sure without inspecting individual data entries that the HashSet iter.next().data only contains data from 1 of the 3 requests?

softwarespartan commented 4 years ago

I guess I’m not sure what you are trying to do. Also, not clear why initBufferForReqId doesn’t fit this purpose? Best to think of buffers/listeners as disposable and make lots of them whenever you need something and delete them as soon as you get response.

Also, it is event programming. That is just the way TWS api works. It’s definitely different from procedural programming. Getting a return value from a method call is very different from make a api call and some time in the future event comes back associated with it.

Sent from my iPhone

On Jul 21, 2019, at 1:28 AM, ecpgieicg notifications@github.com wrote:

For example, let's say 3 historical data requests are made.

javaaddpath(fullfile(pwd,'Jar','TWS973.jar')); session = TWS.Session.getInstance(); session.eClientSocket.eConnect('127.0.0.1',7497,2); [buf,lh] = TWS.initBufferForEvent(TWS.Events.CONTRACTDETAILS); contract = com.ib.client.Contract(); contract.symbol("AMD");contract.secType("OPT");contract.exchange("SMART");contract.currency("USD");contract.lastTradeDateOrContractMonth("20190816");contract.strike(34);contract.right("Call"); session.eClientSocket.reqContractDetails(0,contract); pause(0.5); contract.conid(buf.get().data.iterator().next().contractDetails.conid) [buf,lh] = TWS.initBufferForEvent(TWS.Events.HISTORICALDATA); session.eClientSocket.reqHistoricalData(105,contract,'20190713 16:00:00','1 W','1 min','TRADES',1,1,false,[]); pause(0.5); session.eClientSocket.reqHistoricalData(106,contract,'20190713 16:00:00','1 D','1 min','BID',1,1,false,[]); pause(0.5); session.eClientSocket.reqHistoricalData(102,contract,'20190713 16:00:00','1 W','3 mins','TRADES',1,1,false,[]); pause(0.5); iter=buf.iterator(); Can we know for sure without inspecting individual data entries that the HashSet iter.next().data only contains data from 1 of the 3 requests?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

ecpgieicg commented 4 years ago

I have been trying to download option data (TRADES, BID, ASK) before they expire.

Say AMD Jul 33 Call TRADES for example. I've been requesting the data in 1W 1min increments from the last possible trade time, which ended on Jul 19 at 4pm ET. And I make ~4 requests per batch up to the earliest available data which happens to be on Nov 26, 2018 at 12:32pm ET for this example, and it comes to 9 batches. Whenever a whole batch of 4 weeks' worth of data is returned, I do indeed retrieve and remove everything in the buffer.

My reasoning to do it in such an increments is a bit tentative and merely my best attempt to reduce the frequency of which I experience implicit throttling by the IB server. Requesting data in batches is why I ran into the above question on data integrity. I want to know if returns from separate queries can in theory appear within the same hashset in the buffer.

Now even if the returns from different queries mix, since I am always requesting data for the same financial instrument at one time, sorting at the end will remove any issues. I know that. I just want to stay on the cautious side and learn the basic mechanics for the future.

Indeed, event programming is new to me. I've been trying to understand as much as I can. Thank you very much for your patience!