Perl’s CPAN
contains many gems, and one of them is undoubtedly the Finance::Quote module. Designed to
ease the task of retrieving stock prices off the Internet, the module makes it simple
for developers to integrate stock-tracking mechanisms into their applications
and thus create customized reports on financial market movements over differing
time periods or investment portfolios.

If you’re a Perl developer looking to build a Web-based
stock ticker or portfolio tracker for equity markets and/or mutual funds, keep
reading, because this article will teach you how to:

● Retrieve stock prices
and market data for stocks traded on the major exchanges, such as the NYSE and

● Retrieve mutual fund NAVs from a variety of online sources.

● Create a simple MySQL-based portfolio tracker to display the current value
of an investment basket.


The Finance::Quote package was
originally part of the GnuCash application until it was broken out as a
separate project. The package consists of a base module that provides the
underlying query methods and a series of supplementary modules that take care
of parsing third-party Web sites for the required data. A variety of data
sources are supported, and developers can easily add
new sources as needed.

The package is licensed under the GPL and is currently maintained by Paul Fenwick. You can download
it from the SourceForge site or from the CPAN page.
The download archive provides detailed installation instructions, but by far
the simplest way to install it is to use the CPAN shell:

shell> perl -MCPAN -e shell
cpan> install Finance::Quote

Finance::Quote depends on three
other packages: LWP::UserAgent, HTTP::Request::Common,
and HTML::TableExtractor. If yours is a relatively recent
Perl installation, you’ll probably already have the first two; you can download
the third from this site. If you use the CPAN shell, dependencies will be automatically
downloaded for you (unless you’ve configured your CPAN shell to ignore
dependencies, in which case you’ll need to download and install these three
packages manually).

One important note before you proceed: The data retrieved by
the Finance::Quote module is governed by the terms
and conditions of the source from whence it was retrieved. So before you go out
there and start selling your code to the highest bidder, take a close look at
the license terms and data usage restrictions to ensure that you’re in
compliance. The examples here are purely illustrative. Okay, so let’s start
retrieving stock data

Retrieving stock prices with Finance::Quote

Here’s a simple example of using the Perl Finance::Quote package to retrieve the price of a
fictitious stock (symbol XYZ) from the NYSE:


# import module
use Finance::Quote;

# create object
my $q = Finance::Quote->new();

# retrieve stock quote
my %data = $q->fetch(‘nyse’, ‘XYZ’);

# print price
print “The current price of XYZ on the NYSE is ” . $data{‘XYZ’, ‘price’};

Since Finance::Quote provides an
object-oriented interface, the first step is to create an object with new(). This object exposes a number of methods, including the
fetch() method. This method accepts two arguments: the
name of the data source and the stock symbol.

The data returned by fetch() is
structured as a two-dimensional hash: The first dimension is the stock symbol,
and the second is a label corresponding to the attribute received. The hash
returned by fetch() includes a number of different
labels, some of which are listed below (a complete list is available in the online

price—last trade
high—highest price today
low—lowest price today
volume—number of shares traded today

price range
P/E ratio
nav—net asset
value for mutual fund
exchange—the source exchange
success—Boolean indicating if data
retrieval was successful
string if data retrieval was unsuccessful

So, to retrieve a particular data fragment from the
two-dimensional hash, you’d use the following notation:

$hash(symbol, label)

This is clearly shown in the last line of the example above,
which uses this notation to retrieve the price of XYZ stock.

Tip: You can have fetch()
retrieve more than one quote at a time by specifying a comma-separated list (or
an array) of stock symbols as the second input argument.

Okay, so that’s stock prices. Now let’s look at how to retrieve the NAV
for a mutual fund

Retrieving mutual fund NAV with Finance::Quote

The net
asset value
, or NAV, of a mutual fund is its assets minus its liabilities—in
essence, the net worth of the mutual fund. To retrieve a mutual fund’s NAV
using the Perl Finance::Quote package, simply use the
fetch() method with an appropriate data source and the
mutual fund symbol:


# import module
use Finance::Quote;

# create object
my $q = Finance::Quote->new();

# set mutual fund code
# each fund has a unique code
my $fcode = ‘1#761’;

# retrieve mutual fund NAV
my %quotes = $q->fetch(‘indiamutual’, $fcode);

# print details
if ($quotes{$fcode, ‘success’})
      print “NAV of ” . $quotes{$fcode, ‘name’} . ” is ” . $quotes{$fcode, ‘nav’}; } else
      die “Data retrieval error”;

If Finance::Quote is unable to
retrieve the data successfully, it sets the success key of the return hash to 0
(false) and places an error message in the errormsg
key. By checking for this, you can implement basic error-handling routines into
your Perl script, as I’ve done above.

Note that in many countries (for example, Canada and India),
mutual funds do not have a unique global symbol. In such cases, you’ll need to
manually locate the mutual fund code assigned by the country’s fund watchdog
and use that in your Perl script. Links and instructions on how to accomplish
this are included in the specific Finance::Quote submodule’s documentation.

Now let’s take a look at how your Perl program can retrieve the
available data sources

Retrieving available data sources with Finance::Quote

Since the Perl Finance::Quote package uses data from a variety of
sources, a natural question (especially if you’re letting the user choose the
exchange or region) is: How do you find out which data sources are supported? The
answer: with the sources() method.


# import module
use Finance::Quote;

# create object
my $q = Finance::Quote->new();

# retrieve sources
my @sources = $q->sources();

# print sources
print “Available sources are: “;
foreach $s (@sources)
      print “$s  “, ;

Here’s an example of the output:

Available sources are: vwd  nyse  fidelity_direct  canadamutual  asxaustralia  usa  troweprice  amfiindia  tdwaterhouse  fool  nasdaqbmonesbittburns  trustnet  ftportfolios_direct  yahoo_asia  dutchuk_unit_trusts  canada  troweprice_direct  tiaacref  yahoo  ftportfolios fidelity  fundlibrary  aex  dwsfunds  yahoo_australia  yahoo_europe vanguard  indiamutual  asia  europe

Some of the more important sources in this list are Yahoo!
Finance (in all major world regions), the NYSE and NASDAQ, the Australian Stock
Exchange, and data from Canadian, European, and Asian markets. In some cases,
most notably Asia, you need to suffix the
stock symbol with an exchange identifier as well.

You might notice an overlap among the various source names.
This is because some are specific to exchanges, while others are more general
country databases. For example, use “usa”
for U.S. market data, but “nyse” or “nasdaq” to limit the query to the respective exchanges

Now let’s look at a more detailed example: a simple
portfolio tracker

A simple portfolio tracker with Finance::Quote
and MySQL

With a little imagination, you can use the Perl Finance::Quote package for some very interesting
financial applications. The one I like the most is an online portfolio tracker,
which gives you real-time data on whether your investments are making money or not.
Such an application would store information on your past stock purchases—quantity
and purchase price—and retrieve, on demand or at regular intervals, the latest
prices off the Web for quick comparison and evaluation.

To develop this application, I’ll assume the existence of a MySQL table containing stock symbols, the quantities
purchased of each, and the purchase prices of each. It looks something like

| id | symbol | qty  | pprice |
|  1 | MSFT   |  500 |     17 |
|  2 | YHOO   | 3200 |  45.65 |
|  3 | WMT    |  100 |  53.29 |
|  4 | GE     | 1500 |  12.57 |

This example table holds portfolio information for a single
user. Adding multiuser capability is as easy as
adding a new owner field to each record and filtering by owner in the SQL

The next task is to develop a CGI script to communicate with
MySQL, retrieve the portfolio data, and combine it
with the latest prices from the Web. The original and current prices can then
be compared to offer some insight into whether your portfolio is appreciating
or depreciating, in both absolute and percentage terms (see Listing A).

After sending the standard HTML headers, the script in
Listing A uses the Perl DBI to open a connection to the MySQL
database and query it for the list of stocks, quantities, and original prices.
Then, as it iterates over the record result returned by the query, the Finance::Quote module is used to retrieve the latest price
of each stock. The two prices are then compared, and the change in absolute and
percentage terms is recorded. Once all the records have been retrieved, the
information generated is displayed in a neat table, together with summary

Of course, this is just one of the myriad applications of Finance::Quote. With power like this at your fingertips,
there’s literally a whole world at your disposal. So go on…give your
creativity full rein!