Open mughalgit opened 7 years ago
Hi Adil
Thanks for reaching out.
Looks like everything is functional/correct within your IB4m setup.
That means, it is just an issues getting the historical data call/query to give you back the data you want.
First, please review IB docs for historical data bars and limitations:
https://interactivebrokers.github.io/tws-api/historical_bars.html#gsc.tab=0 <https://interactivebrokers.github.io/tws-api/historical_bars.html#gsc.tab=0>
https://interactivebrokers.github.io/tws-api/historical_limitations.html#gsc.tab=0 <https://interactivebrokers.github.io/tws-api/historical_limitations.html#gsc.tab=0>
For regular stock contracts the requests are fairly simply once you get comfortable with the general query “language”.
Also note that when making historical data requests for Futures and Options the contract configuration takes a bit more work.
Here is a function that I use often to make simple historical data queries for stocks.
function [s,bars] = historicDataQuery(contract,dt,config)
% some randome number for unique request id r = round(rand*10000);
% get TWS session session = TWS.Session.getInstance();
% connect the session to TWS running instance session.eClientSocket.eConnect('127.0.0.1',7496,0);
% create local buffer for historical data events [buf,lh] = TWS.initBufferForEvent(TWS.Events.HISTORICALDATA);
% loop over number of requests for i = 1:config.N
% create unique id
requestId = r+100000+i;
% compute the end time of the request
%endDateTime = datestr(dt-config.delta*(i-1),'yyyymmdd HH:MM:SS');
endDateTime = datestr(dt-config.delta*(i-1),'yyyymmdd 16:00:00');
% make the request for data
session.eClientSocket.reqHistoricalData( ...
requestId ,...
contract ,...
endDateTime ,...
config.duration ,...
config.barsize ,...
config.whatToShow ,...
config.useRTH ,...
1 ,...
[] ...
);
pause(0.5);
end
% wait around for the data pause(3);
% init hde hde = cell(1,buf.size);
% Retreive the historical data event from the buffer for i = 1:buf.size; hde{i} = buf.get(); buf.remove(); end
% Convert the HashSet
% Extract close and high low ave info from each bar`
close = cellfun(@(b)b.close ,bars);
vol = cellfun(@(b)b.volume,bars);
high = cellfun(@(b)b.high ,bars);
low = cellfun(@(b)b.low ,bars);
open = cellfun(@(b)b.open ,bars);
wap = cellfun(@(b)b.wap ,bars);
count = cellfun(@(b)b.count ,bars);
hla = cellfun(@(b)(b.high+b.low)/2,bars);
% Convert the string time of the bars to matlab datenum dt = datenum(cellfun(@(b)char(b.dtstr),bars,'UniformOutput',false),'yyyymmdd HH:MM:SS');
% The bars might not be in order once extracted from the HashSet [~,indx] = sort(dt);
% sort time stamps and get unique dt = dt(indx); [~,uix] = unique(dt);
% sort and assign
s.dt = dt (uix);
close = close(indx); s.close = close(uix);
hla = hla (indx); s.hla = hla (uix);
high = high (indx); s.high = high (uix);
low = low (indx); s.low = low (uix);
open = open (indx); s.open = open (uix);
vol = vol (indx); s.volume = vol (uix);
wap = wap (indx); s.wap = wap (uix);
count = count(indx); s.count = count(uix);
% sort the bars bars = bars(indx); bars = bars(uix);
% clean up listener handle cellfun(@(l)delete(l),lh);
Once you have this function it is easy to make a historical data request. For example:
% date and time for yesterday (-1) dt = now -1;
% lets have a look at some symbol symbol = 'FB';
% create generic contract specification for this symbol contract = com.tws.ContractFactory.GenericStockContract(symbol);
% configure the data request config.symbol = symbol ; config.duration = '1 D' ; config.barsize = '1 min' ; config.whatToShow = 'TRADES'; config.useRTH = 1 ; config.delta = 1 ; config.N = 1 ;
% make the data request for contract [dat,bars] = historicDataQuery(contract,dt,config);
Which returns
dat
dat =
struct with fields:
dt: [390×1 double]
close: [390×1 double]
hla: [390×1 double]
high: [390×1 double]
low: [390×1 double]
open: [390×1 double]
volume: [390×1 double]
wap: [390×1 double]
count: [390×1 double]
When plotting these data and comparing with TWS, the data returned from historical API query and TWS match exactly (see attached plot).
Similarly, if you wanted 3 years of '1 day’ data/bars for ‘FB’ then you would use the configuration:
% configure the data request config.symbol = symbol ; config.duration = '1 Y' ; config.barsize = '1 day' ; config.whatToShow = 'TRADES'; config.useRTH = 1 ; config.delta = 365 ; config.N = 3 ;
Do not hesitate to reach out with additional questions.
Cheers -abel
On Oct 20, 2017, at 6:17 AM, mughalgit notifications@github.com wrote:
Dear Abel,
Firstly, my sincere thanks for putting together this tool and for the online documentation.
I want to be able to request recent historical data for FaceBook. To do this I followed your example (http://softwarespartan.github.io/IB4m/docs/html/HistoricalDataExample.html http://softwarespartan.github.io/IB4m/docs/html/HistoricalDataExample.html) and this works fine. In fact I can compare the graph generated for the close value of FB (for the year of 2014) with the online graph at https://finance.yahoo.com/ https://finance.yahoo.com/ and see that they agree with each other.
However, as a next step I tried adapting your example to get minute-by-minute data for Facebook's close value for the previous day. This is where my problem starts. Here is what I did:
=========================================================================== cd /Users/adilmughal/Applications/IB4m; addpath(path,pwd); addpath(path,fullfile(pwd,'docs')); javaaddpath(fullfile(pwd,'Jar','TWS.jar')); session = TWS.Session.getInstance(); session.eClientSocket.eConnect('127.0.0.1',7497,0); added interface method: TWSNotification notification listener has been added Server Version:76 TWS Time at connection:20171020 10:32:13 Greenwich Mean Time -1 2104 Market data farm connection is OK:hfarm
-1 2104 Market data farm connection is OK:eufarm
-1 2104 Market data farm connection is OK:jfarm
-1 2104 Market data farm connection is OK:usfuture
-1 2104 Market data farm connection is OK:cashfarm
-1 2104 Market data farm connection is OK:usfarm.us
-1 2104 Market data farm connection is OK:usfarm
-1 2106 HMDS data farm connection is OK:ilhmds
-1 2106 HMDS data farm connection is OK:fundfarm
-1 2106 HMDS data farm connection is OK:ushmds
-1 2106 HMDS data farm connection is OK:euhmds
[buf,lh] = TWS.initBufferForEvent(TWS.Events.HISTORICALDATA); contract = com.tws.ContractFactory.GenericStockContract('FB');
session.eClientSocket.reqHistoricalData(1070001,contract,'20171019 16:00:00', '1 D', '1 min', 'TRADES',1,1,[]); pause(0.5);
hde = buf.get(); bars = collection2cell(hde.data); numel(bars)
ans =
90 numel(bars) == hde.data.size()
ans =
logical
1
for i = 1:min(numel(bars),10); disp(bars{i}); end 1070001 20171019 15:48:00 173.47 173.50 173.43 173.48 180 132
1070001 20171019 15:27:00 173.50 173.52 173.35 173.49 308 183
1070001 20171019 15:25:00 173.52 173.58 173.46 173.49 301 195
1070001 20171019 15:21:00 173.74 173.78 173.46 173.66 595 319
1070001 20171019 15:55:00 173.82 173.95 173.81 173.93 396 188
1070001 20171019 15:50:00 173.49 173.73 173.47 173.70 440 209
1070001 20171019 15:37:00 173.33 173.41 173.31 173.39 388 191
1070001 20171019 15:52:00 173.69 173.76 173.66 173.71 251 134
1070001 20171019 15:18:00 173.54 173.73 173.52 173.68 433 210
1070001 20171019 14:56:00 173.10 173.13 172.85 172.88 694 375
===========================================================================
Where in "session.eClientSocket.reqHistoricalData" the time "20171019 16:00:00" represents yesterday's date at 4pm.
My first problem is that I don't understand why I only get 90 bars worth of data (i.e. 1.5 hours worth) - I would have expected to get the entire day's worth.
My second problem is that the data seems to be wrong. So for example the first bar of data is:
1070001 20171019 15:48:00 173.47 173.50 173.43 173.48 180 132
However, according to https://finance.yahoo.com/ https://finance.yahoo.com/ the close value of Facebook at 15:48:00 is 174.35
And in fact if I compare the graph from Yahoo:
https://user-images.githubusercontent.com/32955429/31816421-2a2fb61e-b588-11e7-8c5a-3881373f98e9.jpg with the graph from Matlab/IB4M:
https://user-images.githubusercontent.com/32955429/31816217-605eeb70-b587-11e7-86ce-a8eee4c50245.jpg There is no correspondence between them. I guess I must be doing something fundamentally wrong but I don't understand.
Thank you in advance for your help
A
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/softwarespartan/IB4m/issues/13, or mute the thread https://github.com/notifications/unsubscribe-auth/AEWq1O8irdMwLSTi0Z1m_h7HDjrnNRtPks5suHNMgaJpZM4QAd-i.
Dear Abel,
Firstly - many sincere thanks for replying. Your function "historicDataQuery" works perfectly.
In fact we managed to find the source of the error - I am using GMT (since I am in the UK) and the 16:00 hours is 11:00 in New York - and so the reason I was only getting 90 minutes of data is because the exchange had only been open since 09:30. Once I understood that everything else was fine.
Once again thank you for your assistance - much appreciated.
Dear Abel,
Firstly, my sincere thanks for putting together this tool and for the online documentation.
I want to be able to request recent historical data for FaceBook. To do this I followed your example (http://softwarespartan.github.io/IB4m/docs/html/HistoricalDataExample.html) and this works fine. In fact I can compare the graph generated for the close value of FB (for the year of 2014) with the online graph at https://finance.yahoo.com/ and see that they agree with each other.
However, as a next step I tried adapting your example to get minute-by-minute data for Facebook's close value for the previous day. This is where my problem starts. Here is what I did:
=========================================================================== cd /Users/adilmughal/Applications/IB4m; addpath(path,pwd); addpath(path,fullfile(pwd,'docs')); javaaddpath(fullfile(pwd,'Jar','TWS.jar')); session = TWS.Session.getInstance(); session.eClientSocket.eConnect('127.0.0.1',7497,0); added interface method: TWSNotification notification listener has been added Server Version:76 TWS Time at connection:20171020 10:32:13 Greenwich Mean Time -1 2104 Market data farm connection is OK:hfarm
-1 2104 Market data farm connection is OK:eufarm
-1 2104 Market data farm connection is OK:jfarm
-1 2104 Market data farm connection is OK:usfuture
-1 2104 Market data farm connection is OK:cashfarm
-1 2104 Market data farm connection is OK:usfarm.us
-1 2104 Market data farm connection is OK:usfarm
-1 2106 HMDS data farm connection is OK:ilhmds
-1 2106 HMDS data farm connection is OK:fundfarm
-1 2106 HMDS data farm connection is OK:ushmds
-1 2106 HMDS data farm connection is OK:euhmds
session.eClientSocket.reqHistoricalData(1070001,contract,'20171019 16:00:00', '1 D', '1 min', 'TRADES',1,1,[]); pause(0.5);
ans =
ans =
logical
1
1070001 20171019 15:27:00 173.50 173.52 173.35 173.49 308 183
1070001 20171019 15:25:00 173.52 173.58 173.46 173.49 301 195
1070001 20171019 15:21:00 173.74 173.78 173.46 173.66 595 319
1070001 20171019 15:55:00 173.82 173.95 173.81 173.93 396 188
1070001 20171019 15:50:00 173.49 173.73 173.47 173.70 440 209
1070001 20171019 15:37:00 173.33 173.41 173.31 173.39 388 191
1070001 20171019 15:52:00 173.69 173.76 173.66 173.71 251 134
1070001 20171019 15:18:00 173.54 173.73 173.52 173.68 433 210
1070001 20171019 14:56:00 173.10 173.13 172.85 172.88 694 375
===========================================================================
Where in "session.eClientSocket.reqHistoricalData" the time "20171019 16:00:00" represents yesterday's date at 4pm.
My first problem is that I don't understand why I only get 90 bars worth of data (i.e. 1.5 hours worth) - I would have expected to get the entire day's worth.
My second problem is that the data seems to be wrong. So for example the first bar of data is:
1070001 20171019 15:48:00 173.47 173.50 173.43 173.48 180 132
However, according to https://finance.yahoo.com/ the close value of Facebook at 15:48:00 is 174.35
And in fact if I compare the graph from Yahoo:
with the graph from Matlab/IB4M:
There is no correspondence between them. I guess I must be doing something fundamentally wrong but I don't understand.
Thank you in advance for your help
A