Code covered by the BSD License  

Highlights from
Display Stock Data

Display Stock Data

by

 

24 Jun 2002 (Updated )

Internet enabled data analysis and visualization.

GetStockData(symbol, startdate, frequency, periods)
function [open, high, low, close, date] = GetStockData(symbol, startdate, frequency, periods)
% GETSTOCKDATA Fetch historical prices for a given stock symbol
% Inputs:
%   SYMBOL: String representing the stock symbol
%   STARTDATE: String in MM/DD/YYYY format, or serial date number
%   FREQUENCY: Daily ('d'), Monthly ('m'), or Yearly ('y')
%   PERIOD: Number of data points to return (number of days, months or
%           years)
% Outputs:
% The outputs are all parallel column arrays, with PERIODS number of
% entries. Each day 
%   OPEN: Stock opening price
%   HIGH: High price during that trading day
%   LOW: Low price during that trading day
%   CLOSE: Closing market price
%   DATE: The date for which the data is valid

% Initialize input variables to empty matrices
open = [];
high = [];
low = [];
close = [];
date = [];

% If the input date is a string, convert it to a serial date number
if (isstr(startdate))
    startdate = datenum(startdate);
end

% Query the server for the stock data. Return the stock data as a 
% cell array of strings.
stockdata = QueryServerForData(symbol, startdate, frequency, periods);

% Make the cell array of strings into one long string. The result is 
% a comma-separated list of values, grouped in sets of six: DATE,
% OPEN, HIGH, LOW, CLOSE, VOLUME. This pattern repeats through the
% string.
stockdata = cat(2, stockdata{:});

% Parse the string data into MATLAB numeric arrays. 
if (length(stockdata) > 0)
    [dates, open, high, low, close] = ...
        strread(stockdata,'%s%f%f%f%f%*n', 'delimiter', ',', 'emptyvalue', NaN);
    
    % Convert the string dates into date numbers. The plotting functions
    % need these date numbers.
    date = datenum(dates);
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function stockdata = QueryServerForData(symbol, startdate, frequency, periods)
% QUERYSERVERFORDATA Return stock data from an Internet server as a cell array
% This function uses the historical stock price server at
% finance.yahoo.com. 
% Inputs:
%   SYMBOL: String representing the stock symbol
%   STARTDATE: Serial date number
%   FREQUENCY: Daily ('d'), Monthly ('m'), or Yearly ('y')
%   PERIOD: Number of data points to return (number of days, months or
%           years)

% Build the query string, a specially formatted URL 
urlString = BuildUrlString(symbol, startdate, frequency, periods);

% Send the query to the server by opening the URL. Use the Java URL
% class to establish the connection.
disp('Contacting server...');
url = java.net.URL(urlString);

% Once the connection is established, create a stream object to read the
% data that the server has returned. Use the stream object to create a
% buffered i/o stream object, which allows the use of readLine -- this
% enables us to read an entire line at a time, rather than just a single
% character.
try
    stream = openStream(url);
    ireader = java.io.InputStreamReader(stream);
    breader = java.io.BufferedReader(ireader);
catch
    disp(['Could not connect to stock data server. The server may be unavailable. Please try again later']);
    disp(['URL: ' urlString]);
    stockdata={};
    return;
end

% Skip the first line, which consists only of column header labels
line = readLine(breader);

% Read all the available data. We know we've come to the end of the data
% when the readLine call returns a zero length string. Store the data,
% line by line, into a cell array. These strings will eventually be 
% concatenated into one long string, and parsed by STRREAD, so make 
% sure that each string ends with a comma (this uniformity makes for
% easier parsing).

stockdata = {};
disp(['Reading data for symbol ' upper(symbol) '...']);
while 1
    line = readLine(breader);
    if (prod(size(line)) == 0) 
        break;
    end
    line = char(line);
    if line(end)~=',';line(end+1) = ',';end
    % Store each line in a cell array.        
    stockdata{end+1} = line;
end

% Close the streams, in the opposite order in which they were opened.
close(breader);
close(ireader);
close(stream);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function s = BuildUrlString(symbol, startdate, frequency, periods)
% BUILDURLSTRING Construct a specially formatted URL query string
% Inputs:
%   SYMBOL: String representing the stock symbol
%   STARTDATE: Serial date number
%   FREQUENCY: Daily ('d'), Monthly ('m'), or Yearly ('y')
%   PERIOD: Number of data points to return (number of days, months or
%           years)

% Extract the day, month and year from the starting date
startDay = day(startdate);
startMonth = month(startdate);
startYear = year(startdate);

% Initially, the end date is the same as the starting date
endDay = startDay;
endMonth = startMonth;
endYear = startYear;

% Given the frequency (daily, monthly, yearly), compute the end date
switch frequency
    case 'y' 
        endYear = endYear + periods;
    case 'm'
        endMonth = endMonth + (rem(periods, 12));
        endYear = endYear + (mod(periods, 12));
    case 'd'
        newdate = startdate + periods;
        endDay = day(newdate);
        endMonth = month(newdate);
        endYear = year(newdate);
end        

% The server name is constant, but the query data tagged onto the end of it
% varies according to user input
server = 'http://table.finance.yahoo.com/table.csv';
query = ['?a=' num2str(startMonth) '&b=' num2str(startDay) '&c=' num2str(startYear) ...
         '&d=' num2str(endMonth)   '&e=' num2str(endDay)   '&f=' num2str(endYear) ...
         '&s=' num2str(symbol) '&y=0&g=' num2str(frequency) ];

% Concatenate the server name and query data together into the complete
% query string
s = [ server query ];

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Contact us