www.gusucode.com > trading工具箱matlab源码程序 > trading/trading/@ibtws/timeseries.m

    function d = timeseries(c,s,startdate,enddate,barsize,ticktype,userth,callback)
%TIMESERIES Interactive Brokers aggregated intraday data.
%   TIMESERIES(C,S,STARTDATE,ENDDATE,BARSIZE,TICKTYPE,USERTH,CALLBACK) asynchronously requests Interactive 
%   Brokers aggregated intraday data given the connection handle, C, contract, S, 
%   start date, STARTDATE, end date, ENDDATE, tick aggregation interval, BARSIZE, 
%   and type of ticks, TICKTYPE.  To include from outside of regular trading 
%   hours, set USERTH to false.   To include only from regular trading hours, 
%   set USERTH to true.  The user can specify an event handler, CALLBACK.   
%   If no event handler is specified, the data will be returned
%   as the first output argument, otherwise, a numeric value representing
%   the data request id is returned.
%
%   The data is returned as a Mx9 matrix where the columns are date, open,
%   high, low, close, volume, bar count, wap, and flag indicating if there
%   are gaps in the bar.
%
%   Valid settings for BARSIZE are:
%
%   1 sec
%   5 secs
%   15 secs
%   30 secs
%   1 min
%   2 mins
%   3 mins
%   5 mins
%   15 mins
%   20 mins
%   30 mins
%   1 hour
%   2 hours
%   3 hours
%   4 hours
%   8 hours
%
%   Valid settings for TICKTYPE are:
%
%   TRADES (default)
%   MIDPOINT
%   BID
%   ASK
%   BID_ASK
%   HISTORICAL_VOLATILITY
%   OPTION_IMPLIED_VOLATILITY
%
%
%   For example, 
%
%   ibContract = ib.Handle.createContract;
%   ibContract.symbol = 'XYZ';
%   ibContract.secType = 'STK';
%   ibContract.exchange = 'SMART';
%   ibContract.currency = 'USD';
%   d = ib.timeseries(ibContract,floor(now),now,'5 mins')
%   d = ib.timeseries(ibContract,floor(now),now,'10 mins','BID')
%
%   See also IBTWS, CLOSE, CREATEORDER, GETDATA, HISTORY.

%   Copyright 2013-2015 The MathWorks, Inc. 
   
% Define event handler for error and historical data events
eventNames = {'historicalData'};
tickerID = floor(rand*10000);
if nargin < 8
  for i = 1:length(eventNames)
    c.Handle.registerevent({eventNames{i},@(varargin)ibBuiltInTimeseriesEventHandler(varargin{:},c,tickerID)})
  end
elseif ~isempty(callback)
  for i = 1:length(eventNames)
    c.Handle.registerevent({eventNames{i},callback})
  end
end

% Build duration string for IB API call
startDateNum = datenum(startdate);
endDateNum = datenum(enddate);
daySpan = endDateNum - startDateNum;

% Use later date as end date
if daySpan < 0
  endDateTime = datestr(startDateNum,'yyyymmdd HH:MM:SS');
  daySpan = abs(daySpan);
else
  endDateTime = datestr(endDateNum,'yyyymmdd HH:MM:SS');
end

% Convert date range to duration string
if daySpan < 1
  % Convert to seconds 
  numSecs = ceil(daySpan * (24*60*60));
  durationString = [num2str(numSecs) ' S'];
elseif daySpan < 7
  numDays = ceil(daySpan);
  durationString = [num2str(numDays) ' D'];
elseif daySpan < 31
  numWeeks = ceil(daySpan/7);
  durationString = [num2str(numWeeks) ' W'];
elseif daySpan < 366
  numMonths = ceil(daySpan/31);
  durationString = [num2str(numMonths) ' M'];
else
  numYears = ceil(daySpan/366);
  durationString = [num2str(numYears) ' Y'];
end

% Default tick type is TRADES
if ~exist('ticktype','var') || isempty(ticktype)
  ticktype = 'TRADES';
end

% Determine whether to return all or only data from regular trading hours
if nargin < 7 || isempty(userth)
  userth = false;
end

% IB historical request API call  
c.DataRequest = true;
try
  %Version 9.7+ API call
  c.Handle.reqHistoricalDataEx(tickerID,s,endDateTime,durationString,barsize,ticktype,userth,1,c.Handle.createTagValueList)
catch
  %Version pre 9.7 API call
  c.Handle.reqHistoricalDataEx(tickerID,s,endDateTime,durationString,barsize,ticktype,userth,1)  
end

% If user defined event handler, do not loop on DataRequest property
if nargin > 7 
  d = tickerID;
  return
end

while c.DataRequest
  drawnow
end

% Return data to method workspace
try
  d = evalin('base','ibBuiltInIntraDayData');
catch
  d = evalin('base','ibBuiltInErrMsg');
  evalin('base','clear ibBuiltInErrMsg');
  return
end  

% Clear temporary variables
evalin('base','clear ibBuiltInIntraDayData');

% Convert date strings to date numbers
try
  d(:,1) = num2cell(datenum(d(:,1),'yyyymmdd HH:MM:SS'));
  d = cell2mat(d);
catch
  % IB message is returned
  return
end

% Remove dates outside of request range
i = (d(:,1) < min([startDateNum endDateNum]));
d(i,:) = [];
i = (d(:,1) > max([startDateNum endDateNum]));
d(i,:) = [];

function ibBuiltInTimeseriesEventHandler(varargin)
%IBBUILTINTIMESERIESEVENTHANDLER Interactive Brokers' Trader Workstation built in intraday data event handler.

% Process event based on identifier
persistent ibBuiltInIntraDayData ibBuiltInIntraDayDataCounter
if isempty(ibBuiltInIntraDayDataCounter) 
  ibBuiltInIntraDayDataCounter = 1;
end

% Trap event type
switch varargin{end-2}
  
  case 'historicalData'
    
    % Historical data event
    
    % Get data
    histData = varargin{13};
    
    % Determine if data is last bar
    if strfind(histData.date,'finished')
      % Remove duplicate records
      [~,uniqueDateIndex] = unique(ibBuiltInIntraDayData(:,1));
      ibBuiltInIntraDayData = ibBuiltInIntraDayData(uniqueDateIndex,:);
      
      % Store data in base workspace
      assignin('base','ibBuiltInIntraDayData',ibBuiltInIntraDayData)
    
      % Clear persistent variables and event listeners
      clear ibBuiltInIntraDayDataCounter ibBuiltInIntraDayData
      evtListeners = varargin{1}.eventlisteners;
      i = strcmp(evtListeners(:,1),'historicalData');
      varargin{1}.unregisterevent({evtListeners{i,1} evtListeners{i,2}});
      varargin{1}.cancelHistoricalData(varargin{end});
      varargin{end-1}.DataRequest = false; %#ok
      return
    end
    
    % Populate output array with data from current bar
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,1} = histData.date;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,2} = histData.open;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,3} = histData.high;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,4} = histData.low;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,5} = histData.close;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,6} = histData.volume;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,7} = histData.barCount;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,8} = histData.WAP;
    ibBuiltInIntraDayData{ibBuiltInIntraDayDataCounter,9} = histData.hasGaps;
    ibBuiltInIntraDayDataCounter = ibBuiltInIntraDayDataCounter + 1;
    
end