Remove Finance::Quote from the repository.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7652 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton
2002-12-08 01:08:48 +00:00
parent e9406191ed
commit f3c166b44d
39 changed files with 1 additions and 4865 deletions

View File

@@ -1,3 +0,0 @@
Makefile
blib
pm_to_blib

View File

@@ -1,447 +0,0 @@
2000-04-06 Paul Fenwick <pjf@cpan.org>
* CVSTAG: finance_quote_0_16
* Initial public release.
2000-04-08 Paul Fenwick <pjf@cpan.org>
* Integrated TIAA-CREF changes from Brent Neal.
* Changes to Makefile.PL to check dependancies, etc.
* Updated Examples/Quote_example.pl to include TIAA-CREF examples.
* CVSTAG: finance_quote_0_17
2000-04-10 Paul Fenwick <pjf@cpan.org>
* Changed Examples/chkshares.pl to print a pretty table.
* Incorporated Cooper Vertz's patch to add high, low and net change
to quotes obtained from Yahoo!
2000-04-13 Paul Fenwick <pjf@cpan.org>
* Fidelity private functions renamed to indicate they are private.
* Small optimisations in fidelity functions to avoid spurious warnings
and un-needed processing of non-useful lines.
* Functions now quickly return undef when not passed a list of stocks.
Previously they would waste time looking up nothing.
* Documentation additions and corrections.
* Added test files (Use.t, asx.t, yahoo.t, fidelity.t)
* Added experimental function (currency) to look-up conversion
rates between currencies.
* Added an example script (currency-lookup.pl) to test said
currency conversion.
2000-04-14 Paul Fenwick <pjf@cpan.org>
* Added TIAA-CREF testing script.
* Added troweprice testing script.
2000-04-16 Paul Fenwick <pjf@cpan.org>
* Added yahoo_europe test script.
* Removed depreciated vanguard function.
2000-04-18 Paul Fenwick <pjf@cpan.org>
* Added fetch() function to provide a cleaner interface to fetching
quotes from a variety of sources.
* Added tests for fetch() to the asx.t test script.
2000-04-20 Paul Fenwick <pjf@cpan.org>
* Removed misleading comments from Finance::Quote.pm
2000-04-21 Paul Fenwick <pjf@cpan.org>
* Added extra methods to fetch (nasdaq, nyse) which act as
aliases to yahoo.
* Added stockdump.pl example script, which is handy in debugging.
* fetch is now an exportable function.
* yahoo() function no longer returns entries for fields that
used to be returned as 'N/A'.
* yahoo() now supports the $stocks{$sym,'success'} notation.
2000-04-21 Brent Neal <brentn@users.sourceforge.net>
* Added checking for bogus symbols in tiaacref
* Added checking of the LWP::UserAgent->is_success method
* tiaacref() now supports $stocks{$sym,'success'} notation.
* Updated t/tiaacref.t and Examples/Quote_example.pl for
the changes
2000-04-23 Paul Fenwick <pjf@cpan.org>
* Added success/fail tests to asx, fidelity, troweprice, yahoo
and yahoo_europe.
* Updated appropriate testing functions.
* Updated documentation to include fetch and list of known
bugs.
* Updated yahoo_europe to return undef's instead of N/As.
* Removed HTML from returns from yahoo_europe.
* Fixed logic bug in process yahoo_* N/As into undefs.
2000-04-24 Paul Fenwick <pjf@cpan.org>
* Updated in-line code regarding checking for Yahoo!
successes.
* Added meaningful error-messages to Yahoo! when stock
lookups fail.
2000-04-24 Brent Neal <brentn@users.sourceforge.net>
* Finished updating error-checking for tiaacref. The tiaacref
function now returns a success/failure flag for every symbol
passed to it. It also checks that the data is valid. Returns
meaningful error messages for these failures.
2000-04-25 Paul Fenwick <pjf@cpan.org>
* Rolled changes together when CVS got a little out-of-whack. :)
* Return many new fields from yahoo() which we previously fetched
but did not use. These include avg_vol, day_range, year_range,
div_date, div, and div_yield.
* Fixed typo in docs s/yeild/yield/;
* Added ex_div for Ex-Divident Date in yahoo().
2000-04-30 Paul Fenwick <pjf@cpan.org>
* Updated POD.
* Improved returned error messages.
* Updated the README file.
* Updated the INSTALL file.
* Tagged files as finance_quote_0_18 for release.
2000-05-13 Paul Fenwick <pjf@cpan.org>
* Added Documentation/FAQ file.
2000-05-14 Paul Fenwick <pjf@cpan.org>
* Huge re-write and change of everything so that it should be easy
to plug in new modules without changing any existing code.
2000-05-27 Paul Fenwick <pjf@cpan.org>
* Added Documentation/Hackers-Guide.
* Tweaked Quote.pm to provide an AUTOLOAD method for those people
who don't want to go through the fetch() methods.
2000-05-31 Paul Fenwick <pjf@cpan.org>
* Added Documentation/TODO.
2000-06-03 Paul Fenwick <pjf@cpan.org>
* Revived dead vanguard method by rolling it through Yahoo.
* Added labels method to everything.
* Added price labels to everything.
* Updated Quote.pm to query new labels methods.
* Provided a failover method for fidelity via Yahoo.
* Added failover functionality.
2000-06-03 Jacinta Richardson <jarich@users.sourceforge.net>
* Changed modules so they return undef in scalar context,
empty list in list context, on failure.
* Changed modules so they return a hashref when in scalar
context, and a hash in list context.
* Reviewed/corrected hackers guide.
* Added currency tags to existing modules to signal currency type
(AUD, EUR, USD)
* Added tests to check currency tags.
2000-06-16 Paul Fenwick <pjf@cpan.org>
* Added webpage to CVS repository.
2000-06-17 Paul Fenwick <pjf@cpan.org>
* Re-added currency lookups to Quote.pm
* Added regression testing script for currency.
* Added automatic currency conversion stub.
* Removed TODO file as we now keep track of outstanding jobs
in SourceForge.
2000-06-21 Paul Fenwick <pjf@cpan.org>
* Rolled all the Yahoo functions into a base pseudo-class.
* Fixed bug whereby large lookups in the yahoo functions would
overflow the maximum URL length of some proxies/servers.
* Expanded the number of fields available via Yahoo::Europe.
2000-06-22 Paul Fenwick <pjf@cpan.org>
* Added sections on currency conversion to the hacker's guide.
Now I just need to write the code. :)
# Added currency conversion code, but haven't tested it yet.
2000-06-23 Paul Fenwick <pjf@cpan.org>
* Cleaned up the hacker's guide.
* Updated Examples/stockdump.pl to allow currency to be specified.
* Automatic currency conversion now works.
* Updated ASX and Yahoo::USA to not tag indexes with currency
labels.
* Updated Yahoo::Base to automatically accomodate suffixes for
when we wish to add them automatically.
* Added Yahoo::Australia to look up Australian stocks.
* Tested failover of Yahoo::Australia to Yahoo::ASX.
2000-06-24 Paul Fenwick <pjf@cpan.org>
* Updated currency regression testing script.
* Updated currency fetching routines to handle different date
formats returned by Yahoo!
* Updated automatic currency conversion routines to avoid
spurious warnings.
2000-06-25 Paul Fenwick <pjf@cpan.org>
* Documented many of the new 0.19 functions in the Finance::Quote
POD.
2000-07-02 Paul Fenwick <pjf@cpan.org>
* Many more documentation improvements in both the Finance::Quote
POD and the sub-modules.
2000-07-08 Paul Fenwick <pjf@cpan.org>
* Added POD for TIAA-CREF and T. Rowe Price sub-modules.
2000-07-13 Paul Fenwick <pjf@cpan.org>
* Improved fidelity module such that it doesn't return information
about stocks we did not request.
2000-07-15 Paul Fenwick <pjf@cpan.org>
* Wrote documentation for Yahoo::Europe (incomplete) and
Yahoo::USA. Changed modules to require perl 5.005 because
we make use of some of its features (like hash slices).
* Improved labels documentation in Finance::Quote.
* Added exchange and method information (where possible)
to the various sub-modules.
* Improved chkshares example script to check for errors.
* Removed bad test in currency.t and replaced it with a better
one.
2000-07-16 Paul Fenwick <pjf@cpan.org>
* Documented the list of possible markets in Yahoo::Europe.
* Many many small syntax fixes in documentation.
* Expanded and improved webpage.
* Updated revision to 1.00
* Updated INSTALL documentation.
* CVSTAG: finance_quote_1_00
2000-07-25 Paul Fenwick <pjf@cpan.org>
* Finance::Quote::Yahoo::Base now removes more HTML-ish guff that
Yahoo tries to place in CSVs.
* Updated yahoo_europe.t to check that stocks from London are in
GBP.
* Finance::Quote::Yahoo::Europe now returns London stocks in
GBP. Previously it was incorrectly returning them in pence
and calling it Euros.
* Finance::Quote has a new scale_field() function that is used in
currency conversion and by some sub-modules (Yahoo::Europe). This
may be useful for future module writers.
* CVSTAG: finance_quote_1_01
2000-07-31 Paul Fenwick <pjf@cpan.org>
* The currency function no longer makes an expensive HTTP
request if both the to and from currencies are identical.
2000-08-04 Paul Fenwick <pjf@cpan.org>
* Patched Yahoo::Base to no longer return spurious percentage signs.
2000-08-06 Paul Fenwick <pjf@cpan.org>
* Updated regression testing scripts to make sure that spurious
percentage signs are no longer returned.
2000-08-14 Paul Fenwick <pjf@cpan.org>
* Updated chkshares script so that it can deal with any market,
not just the ASX.
2000-08-16 Paul Fenwick <pjf@cpan.org>
* Added DWS.pm module to the CVS repository, courtesy of
Volker Stuerzl. This module fetches information from the
Deutsche Bank Gruppe.
* Updated asx.t script because it really hurts the entire
"make test" thing when ASX is unhappy. Now it still hurts
(because the ASX module sucks), but less.
2000-08-21 Paul Fenwick <pjf@cpan.org>
* Improved documentation in the yahoo_europe test script.
2000-08-22 Volker Stuerzl <volkers@users.sourceforge.net>
* Added DWS test script.
2000-08-29 Paul Fenwick <pjf@cpan.org>
* Rejiggered ASX module to try and make it work again after
an ASX site rewrite.
* Updated Quote.pm so that if a method was called directly
(old-style) not through fetch, then it would do the right
thing if called via an object. This means that things
like $q->asx(@stocks) work correctly again.
* Updated fetch() method so that it returns the empty list
rather than undef when called in an array context.
* fetch() now returns a hashref if called in a scalar context.
2000-08-31 Paul Fenwick <pjf@cpan.org>
* Added Keith Refson's Trustnet module.
* Added .cvsignore file to reduce spam for developers using CVS.
* Updated Yahoo/USA.pm to provide more compatible returns when
called as a fidelity failover.
* Tweaked DWS.t testing script so that it loads the module
correctly.
2000-09-01 Paul Fenwick <pjf@cpan.org>
* Tweaked ASX.pm to avoid divide-by-zero errors and dodgy
bogus-looking label values.
2000-09-04 Paul Fenwick <pjf@cpan.org>
* Keith Refson's patch to Trustnet to avoid premature returns
in case of a bad symbol.
2000-09-12 Paul Fenwick <pjf@cpan.org>
* Mention of Bill Bell's java library in the FAQ.
2000-09-16 Paul Fenwick <pjf@cpan.org>
* Added Volker's VWD module and testing script.
* Updated Makefile to check for HTML::TableExtract.
* Updated INSTALL file to provide infomation on how to install
modules that F::Q depends upon.
* Updated Quote.pm to load VWD, DWS and Trustnet by default.
* Updated README file to mention the webpage.
* Added Trustnet regression testing program.
* CVSTAG: finance_quote_1_02
2000-09-27 Paul Fenwick <pjf@cpan.org>
* Updated Trustnet module with patch from Keith Refson.
2000-10-20 Paul Fenwick <pjf@cpan.org>
* Much better discovery of non-existant stocks in ASX.pm.
* Checks for possible divide-by-zero problems in ASX.pm.
Thanks to Stephen Stebbing for catching this.
* Updated ASX testing.
* Updated all test scripts to remove spurious warnings under
Perl 5.6.
* Updated ASX module to deal with stocks when they have market
announcements. Previously this would result in garbage being
returned for that stock.
* Updated VWD module so it can parse information from the new
VWD site.
* Updated F::Q version to 1.03.
* CVSTAG: finance_quote_1_03
2000-10-27 Paul Fenwick <pjf@cpan.org>
* Updated yahoo_europe test suite as one of the symbols we were
using for testing has since dissapeared. (Bankrupt? Merged?)
2000-10-29 Paul Fenwick <pjf@cpan.org>
* F::Q now makes use of a custom F::Q::UserAgent to fetch
information. This is capable of doing proxy authentication
and other arbitary http-headers.
2000-11-05 Paul Fenwick <pjf@cpan.org>
* BUG 121557: Fixed bug where the 40th symbol in a Yahoo lookup
would fail.
* F::Q::UserAgent is now ready for release, but is still considered
experimental. Users must explicitly turn it on by setting
$Finance::Quote::USE_EXPERIMENTAL_UA = 1;
* Updated the FAQ.
* Added MANIFEST file.
* CVSTAG: finance_quote_1_04
2000-11-21 Paul Fenwick <pjf@cpan.org>
* Extra code to ensure that currency-fields returned by a
Quotelet are unique. This prevents the potential bug of
a field undergoing currency conversion multiple times and
hence being quite off-track.
2000-11-29 Paul Fenwick <pjf@cpan.org>
* Updated the URL we obtain currency information to
http://uk.finance.yahoo.com/m5?"
* Updated docs in Yahoo/Europe.pm to note the Xtera exchange
moving from FX to DE.
* Thanks to Jan Willamowius for the above two changes.
2000-12-05 Paul Fenwick <pjf@cpan.org>
* Updated the Yahoo::USA source to finance.yahoo.com as
the quote.yahoo.com may become depreciated in the future.
Thanks to Iain Lea for spotting this.
2000-01-22 Paul Fenwick <pjf@cpan.org>
* Updated to respect the FQ_LOAD_QUOTELET environment variable
to auto-load custom Quotelet.
2000-02-16 Paul Fenwick <pjf@cpan.org>
* Updated to repsect formatting changes in data fed to the
currency function.
* Updated Quote.pm to include updated information on
FQ_LOAD_QUOTELET
* CVSTAG: finance_quote_1_05

View File

@@ -1,95 +0,0 @@
Finance::Quote FAQ
Paul Fenwick (pjf at cpan.org)
0. TABLE OF CONTENTS
====================
0. Table of Contents.
1. Where's the Finance::Quote webpage?
2. Where can I get a beginner's introduction to F::Q?
3. What does it mean if "make test" fails?
4. How can I use proxyauth (experimental)?
5. Is there anything similar to F::Q in other languages?
6. Where can I get more help?
1. Where is the Finance::Quote webpage?
=======================================
http://finance-quote.sourceforge.net/
2. Where can I get a beginner's introduction to F::Q?
=====================================================
A good beginner's guide is the Finance::Quote article in
The Perl Journal (http://www.tpj.com/) edition #19. If you
don't have a subscription to TPJ, you can also read the
final draft of this essay at
<http://finance-quote.sourceforge.net/documentation.html>.
3. What does it mean if "make test" fails?
==========================================
Finance::Quote performs a number of tests to try and ensure good
operation of its modules. These rely upon a good network connection
and the quote-sources providing the data used for testing. Sometimes,
a test will fail intermittently, this is sometimes caused by a
slow link or network congestion, and is nothing to be worried
about.
If a particular test continues to fail, then it may indicate a
problem. Normally a failed test only indicates a problem with
a particular module, and this will only affect you if you're
using that module to obtain data. Sometimes, if you're using
failover support (which is on by default), this isn't even an
issue.
Before each version of F::Q is released, checks are made to ensure
that all tests are passed. Sometimes the data that F::Q uses for
its tests becomes invalid (eg, if a stock no longer exists). In
this case it will be corrected in the next version of F::Q.
If you think you've found a bug, or want to know if others are
experiencing similar problems to you, you can visit the F::Q
bug-tracking system via
http://finance-quote.sourceforge.net/developer.html
4. How can I use proxyauth (experimental)?
==========================================
WARNING: THIS SUPPORT IS EXPERIMENTAL AND SYNTAX _WILL_ CHANGE IN
THE FUTURE. USE AT YOUR OWN RISK.
Finance::Quote provides experimental support for authenticated
proxies. If you wish to try this, then put the following at the
top of your script.
use Finance::Quote;
$Finance::Quote::USE_EXPERIMENTAL_UA = 1;
This adds extra features on top of the regular LWP::UserAgent
class. In particular, you can now do things like this:
my $q = Finance::Quote->new();
$q->user_agent->default_headers->proxy_authorization_basic($user,$pass);
The result of $q->user_agent->default_headers is a HTTP::Headers
object, and can use all the regular HTTP::Headers methods.
This object is used as a template for any new HTTP requests made by
Finance::Quote.
5. Is there anything similar to F::Q in other languages?
========================================================
Vidyut Luther has written a stock-lookup library in PHP. It's
available at <http://www.gotslack.com/stocks/>
Bill Bell has written a stock-lookup library in Java. It's
available at <http://www.aboutbillbell.com/>. Follow the
"Code Downloads" link in the left sidebar.
6. Where can I get more help?
=============================
If you haven't already done so, try the Finance::Quote webpage
at <http://finance-quote.sourceforge.net/>. There are also lots
of fun things like bug-tracking systems, support requests, forums,
and other goodies at <https://sourceforge.net/projects/finance-quote/>.
Finally, you can always try sending mail to the Finance::Quote
developer's list, at <finance-quote-devel@lists.sourceforge.net>.
The archives of this list are available on-line at
<http://sourceforge.net/mail/?group_id=4232>.

View File

@@ -1,283 +0,0 @@
Finance::Quote Hackers Guide
Paul Fenwick <pjf@cpan.org>, May 2000
$Version$
0. Table of Contents
====================
1. Introduction
2. How to write a Finance::Quote module.
2.1. The package name.
2.2. The methods() subroutine.
2.3. The functions specified by methods().
2.4. Currency.
2.5. Thngs to avoid.
2.6. Using your new module.
3. How to contribute your module to the world.
4. How to find out more?
5. How to join the mailing lists?
1. Introduction
===============
This hacker's guide is primarily a tutorial on how to build your own
Finance::Quote pluggable module. After reading this guide, you should
be able to write your own module to provide extra methods and functionality
to the Finance::Quote library.
This guide assumes that you are familiar with perl.
2. How to write a Finance::Quote module
=======================================
Finding a source of information, and writing code to parse and interpret
that information is a difficult task. As such, we've aimed to make
writing a Finance::Quote module as easy as possible. There are only
a few simple rules you need to follow:
2.1. The package name.
----------------------
Finance::Quote expects that its loadable modules will be in the
Finance::Quote namespace somewhere. Hence, if you were writing
a module called "DodgyBank" that returned information on DodgyBank's
managed funds, a reasonable name for that module would be
Finance::Quote::DodgyBank.
2.2. The methods() subroutine.
------------------------------
Your module must have a subroutine named methods(). This function will
be called by the Finance::Quote harness when it loads your module, and
is used to determine which methods your module provides. The methods()
function must return a hash of method names and subroutine references.
For example, if you had written a module which provides access to
DodgyBank's managed funds, you might have the following
package Finance::Quote::DodgyBank;
sub methods { return ( dodgyfunds => \&funds
dodgyloans => \&loans ); }
This would indicate that your package provides methods for
"dodgyfunds" and "dodgyloans", and that the subroutines
"funds" and "loans" should be called to access that information.
The following method names should be used for the following information
sources:
Method-Name Source
---------------------------------------------------------
australia Australian Stocks
canada Canadian Stocks
europe European Stocks
fidelity Fidelity Investments
nasdaq NASDAQ
nyse New York Stock Exchange
tiaacref TIAA-CREF
troweprice T. Rowe. Price
usa USA Stocks
Method names should be lower-case, consist of alphanumeric characters
(including underscore) only, and always begin with a letter. This is
not enforced, but future versions of the Finance::Quote framework may
rely upon it.
It's strongly recommended that you also provide a unique name for your
method, in case you (or others) wish to call that method exclusively
in code. Hence if you had written a module to fetch information from
the NYSE from Yohoo!, you might implement the following methods
function:
sub methods { return ( nyse => \&yohoo,
yohoo => \&yohoo ); }
This means that people who only want to use your function can use
$quoter->fetch('yohoo',@stocks), but those who don't care where
their NYSE stock information is fetched from can use
$quoter->fetch('nyse',@stocks). The first form allows you to know exactly
where the information is coming from. In the second, failover methods mean
that many different functions could be used to fetch the stock information,
not just the one you have defined.
2.3 The functions specified by methods().
-----------------------------------------
The functions referred to by methods() will be passed a Finance::Quote
object when called, and a list of zero or more symbol names. The
Finance::Quote object provides the following ready-to-use methods:
user_agent(); # Provides a ready-to-use LWP::UserAgent
parse_csv(); # Parses a list of comma-separated values
# and returns an array.
The user_agent() method should be used if possible to fetch the information,
as it should be already configured to use the timeout, proxy, and other
settings requested by the calling program.
Your function should return a two-dimensional hash as specified in the
Finance::Quote man-page. Eg:
$hash{$symbol,'last'} = $last_price;
$hash{$symbol,'name'} = $stock_name;
# etc etc.
When returning your hash, you should check the context that your
function was called in. If it was called in a scalar context, then
you should return a hashref instead. This can be easily done
with the following:
return wantarray() ? %hash : \%hash;
It is ESSENTIAL that your hash contain a true value for {$symbol,'success'}
for information that has been successfully obtained. If the information
was not obtained for any reason, then {$symbol,'success'} should
be set to a false value (preferably 0), and a human-readable error
message placed in {$symbol,'errormsg'}. The following code snippet
demonstrates this:
sub funds {
my $quoter = shift; # The Finance::Quote object.
my @stocks = @_;
my %info;
my $DODGY_URL = "http://dodgybank.xxx/funds.csv?";
my $ua = $quoter->user_agent; # This gives us a user-agent
# with timeouts, proxies,
# etc already configured.
my $response = $ua->request(GET $DODGY_URL);
unless ($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock,"success"} = 0;
$info{$stock,"errormsg"} = "HTTP failure";
}
return wantarray ? %info : \%info;
}
# Do stuff with the information returned....
}
It is valid to use "return" with no arguments if all stock lookups failed,
however this does not provide any information as to WHY the lookups
failed. If at all possible, the errormsg labels should be set.
It is also very very strongly recommended that you place your module's
name in the {$stock,"source"} field. This allows others to check where
information was obtained, and to use it appropriately.
2.4. Currency
-------------
Finance::Quote has support for multiple currencies and for currency
conversion. As long as you provide a little bit of information about
the information you are returning, the Finance::Quote framework can
do all the hard stuff for you.
If you are returning information on a stock in a particular currency,
then you can enter the ISO currency code into the "currency" field
associated with the stock. Eg:
$info{$stock,"currency"} = "AUD"; # Australian Dollars
If the information you are returning does not have a currency
(because it's an index like the Dow Jones Industrial or the
All Oridinaries, or because you're returning percentages) then
you should not set the currency field for that stock. Finance::Quote
knows not to attempt currency conversion for stocks without
a currency field.
If you do have a currency field, then by default Finance::Quote will
arrange for the automatic conversion of a number of fields. By
default, these fields are last, high, low, net, bid, ask, close, open,
day_range, year_range, eps, div, cap, nav and price. Of course,
there may be some cases where this set is not appropriate, or where there
are extra fields that should be converted. This can be indicated
by writing a function called "currency_fields()" in your module,
that returns a list of fields that can undergo currency conversion.
Eg:
sub currency_fields {
return qw/high low price bid/;
}
currency_fields() will be passed a Finance::Quote object as its
first argument, and a method called default_currency_fields()
is available through this object. This is useful if you want
to use the defaults, but also add some of your own:
sub currency_fields {
my $quoter = shift;
return ($quoter->default_currency_fields, "commission");
}
In the example above, the default fields would be available for currency
conversion, but the "commission" field would also be converted.
2.5. Things to avoid
--------------------
Some sources of information will provide more stock information than
requested. Some code may rely upon your code only returning information
about the stocks that the caller requested. As such, you should
never return information about stocks that were not requested, even
if you fetch and/or process that information.
2.6. Using your new module
--------------------------
Using your new module is easy. Normally when using Finance::Quote you'd
do something like the following:
use Finance::Quote;
my $quoter = Finance::Quote->new();
To use your new module, simply specify the module name (without
the Finance::Quote prefix) in the new function. Hence:
use Finance::Quote;
my $quoter = Finance::Quote->new("DodgyBank");
The DodgyBank methods will now be available:
my %loaninfo = $quoter->fetch("dodgyloans","car","boat","house");
my %fundinfo = $quoter->fetch("dodgyfunds","lotto","shares");
The resulting Finance::Quote object will also arrange for your functions
to be callable without using fetch. This syntax is strongly discouraged,
as it results in pollution of the Finance::Quote namespace and provides
little advantages over the fetch() method:
my %loaninfo = $quoter->dodgyloans("car","boat","loan");
This mainly exists to maintain compatibility with previous versions of
Finance::Quote.
3. How to contribute your module to the world.
==============================================
If you'd like others to use your module, then send a post to
<finance-quote-devel@sourceforge.net>
to get in touch with the other finance-quote developers and maintainers.
You can also submit your module using the patch manager at:
http://sourceforge.net/project/?group_id=4232
4. How to find out more?
========================
The Finance::Quote webpage is located at:
http://finance-quote.sourceforge.net/
You are welcome to make use of the tools at:
http://sourceforge.net/project/?group_id=4232
5. How to join the mailing lists?
=================================
There are two mailing lists for Finance::Quote. These can both be accessed
from:
http://sourceforge.net/mail/?group_id=4232

View File

@@ -1,340 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -1,39 +0,0 @@
Welcome to Finance::Quote
=========================
Maintained by: Paul Fenwick <pjf@cpan.org>
What does Finance::Quote provide?
=================================
Finance::Quote provides access to time-delayed stockquotes from a
number of sources. After you've installed the pacakage, try
'perldoc Finance::Quote' for full information. Alternatively,
you can 'perldoc lib/Finance/Quote.pm' before the install.
How do I install this package?
==============================
See the `INSTALL' file. It's very simple.
I've found a bug / written a patch / have an idea. What do I do?
=================================================================
Well, you could always mail it to <finance-quote-devel@lists.sourceforge.net>,
which is read by all the active developers. Alternatively, you
might wish to visit <http://sourceforge.net/project/?group_id=4232>
and make use of the patch manager, bug tracker, or public forums.
How do I download the most recent copy of Finance::Quote?
=========================================================
You can find all releases of Finance::Quote at:
<http://sourceforge.net/project/filelist.php?group_id=4232>.
You might also wish to consider subscribing to finance-quote-news,
which can be done from: <http://sourceforge.net/mail/?group_id=4232>.
How can I get a copy of the current CVS development tree?
=========================================================
Check out the instructions at <http://sourceforge.net/cvs/?group_id=4232>.
You can also browse the repository using your web-browser at this site.
Where can I find more information?
==================================
Try the Finance::Quote webpage. There are lots of goodies there.
http://finance-quote.sourceforge.net/

View File

@@ -1,92 +0,0 @@
#!/usr/bin/perl -w
#
# example script showing how to use the Quote perl module.
# gets prices for some stocks, for some mutual funds
#
# This script was originally part of GnuCash.
use lib '../lib';
use Finance::Quote;
my $q = Finance::Quote->new();
# -----------------------------------
# get quotes for two stocks ...
%quotes = $q->yahoo ("IBM", "SGI");
# print some selected values
print "NYSE by Yahoo: ", $quotes {"IBM", "name"},
" last price: ", $quotes {"IBM", "last"}, "\n";
print "NYSE by Yahoo: ", $quotes {"SGI", "name"},
" last price: ", $quotes {"SGI", "last"}, "\n";
# loop over and print all values.
# Notes that values are stored ion a multi-dimensional associative array
foreach $k (sort (keys %quotes)) {
($sym, $attr) = split ($;, $k, 2);
$val = $quotes {$sym, $attr};
# $val = $quotes {$k}; # this also works, if desired ...
print "\t$sym $attr =\t $val\n";
}
print "\n\n";
# -----------------------------------
# get quotes from Fidelity Investments
@funds = ("FGRIX", "FNMIX", "FASGX", "FCONX");
%quotes = $q->fidelity (@funds);
foreach $f (@funds) {
$name = $quotes {$f, "name"};
$nav = $quotes {$f, "nav"};
print "Fidelity Fund $f $name \tNAV = $nav\n";
}
print "\n\n";
# -----------------------------------
@funds = ("FGRXX");
%quotes = $q->fidelity (@funds);
print "Not all funds have a NAV; some have Yeilds:\n";
foreach $f (@funds) {
$name = $quotes {$f, "name"};
$yield = $quotes {$f, "yield"};
print "\tFidelity $f $name 30-day Yield = $yield percent\n";
}
print "\n\n";
# -----------------------------------
# demo T. Rowe Price -- same as above
@funds = ("PRFDX", "PRIDX");
%quotes = $q->troweprice (@funds);
foreach $f (@funds) {
$nav = $quotes {$f, "nav"};
$dayte = $quotes {$f, "date"};
print "T. Rowe Price $f NAV = $nav as of $dayte\n";
}
print "\n\n";
# -----------------------------------
# demo for ASX. Grab the price of Coles-Myer and Telstra
@funds = ("CML","TLS");
%quotes = $q->asx(@funds);
foreach $f (@funds) {
print "ASX Price of $f is ".$quotes{$f,"last"}." at ".
$quotes{$f,"date"}."\n";
}
print "\n\n";
# Demo for TIAA-CREF.
@funds = qw/CREFstok BOGOname TIAAreal CREFmony/;
%quotes = $q->tiaacref(@funds);
foreach $f (@funds) {
if ($quotes{$f,"success"} == 1) {
print "TIAA-CREF Price of ".$quotes{$f,"name"}." is ".$quotes{$f,"nav"}.
" at ".$quotes{$f,"date"}."\n";
} else {
print "Error: ".$quotes{$f,"errormsg"}." for ".$f."\n";
}
}
print "\n\n";

View File

@@ -1,55 +0,0 @@
#!/usr/bin/perl -w
use strict;
use lib '../lib';
use Finance::Quote qw/asx/;
=head1 NAME
chkshares.pl - Check share information.
=head1 USAGE
chkshares.pl australia TLS CML ITE
=head1 NOTES
Example program. Demonstrates how to use one of the interface to
Finance::Quote. The first argument must be the market.
=cut
my ($name, $date, $last, $p_change, $high, $low, $volume, $close);
format STDOUT_TOP =
STOCK REPORT
TICKER DATE LAST %CHANGE HIGH LOW VOLUME CLOSE
-------------------------------------------------------------------------------
.
format STDOUT =
@<<<<<< @>>>>>>>>>> @###.### @###.### @###.### @###.### @>>>>>>>> @###.###
$name, $date, $last, $p_change, $high, $low, $volume, $close
.
my $quoter = Finance::Quote->new();
my $market = shift || die "Usage: $0 market stocks\n";
my %quote = $quoter->fetch($market,@ARGV);
foreach my $code (@ARGV) {
unless ($quote{$code,"success"}) {
warn "Lookup of $code failed - ".$quote{$code,"errormsg"}."\n";
next;
}
$name = $code;
$date = $quote{$code,'date'};
$last = $quote{$code,'last'};
$p_change = $quote{$code,'p_change'};
$high = $quote{$code,'high'};
$low = $quote{$code,'low'};
$volume = $quote{$code,'volume'};
$close = $quote{$code,'close'};
write;
}

View File

@@ -1,20 +0,0 @@
#!/usr/bin/perl -w
use strict;
use lib '../lib';
use Finance::Quote;
# This script demonstrates how currencies can be converted using
# Finance::Quote.
# Example usage: currency-lookup.pl USD AUD
# (Converts from US Dollars to Australian Dollars)
die "Usage: $0 FROM TO\n" unless defined($ARGV[1]);
my $q = Finance::Quote->new();
my $exchange_rate = $q->currency($ARGV[0],$ARGV[1]);
die "Urgh! Nothing back\n" unless $exchange_rate;
print $ARGV[0]."->".$ARGV[1]." = ".$exchange_rate."\n";

View File

@@ -1,26 +0,0 @@
#!/usr/bin/perl -w
use strict;
use lib '../lib';
use Finance::Quote;
use Data::Dumper;
use Getopt::Std;
# A very very simple script. Takes a source and a symbol, looks it up,
# and dumps it to STDOUT. Useful for debugging.
my %options = ('c' => '');
getopts('c:',\%options);
die "Usage: $0 [-c currency] source symbol\n" unless (defined $ARGV[1]);
my $q = Finance::Quote->new;
if ($options{'c'}) {
$q->set_currency($options{'c'});
}
my %quotes = $q->fetch(@ARGV);
print Dumper(\%quotes);

View File

@@ -1,73 +0,0 @@
Finance::Quote
==============
IMPORTANT
=========
Read Documentation/License for the license (GPL) covering this code.
Dependancies
------------
Finance::Quote depends upon a number of other perl modules to
function correctly. These modules include:
LWP::UserAgent
HTTP::Request::Common
HTML::TableExtract
You will receive a warning during the make process if one or more of
these modules are missing.
One easy way to install the modules that Finance::Quote requires is
to use perl's CPAN module:
hostname$ perl -MCPAN -e shell (as root)
If you haven't used the CPAN module before, then it may ask you a few
simple configuration questions before you get to the cpan> prompt.
You can install any module from CPAN using:
cpan> install my::module
Indeed, it's possible to install Finance::Quote and all the modules
it depends upon using:
cpan> install Finance::Quote
Install instructions
--------------------
$ perl Makefile.PL
$ make
$ make test (optional)
# make install (as root)
Couldn't be easier, could it?
The tests do take some time to run (especially the currency test), so
please be patient.
What if my tests fail?
----------------------
Your tests could fail if your machine does not have a connection to the
Internet, if your machine must use an HTTP proxy and you do not have
your http_proxy environment variable set, or if one or more of the
servers that Finance::Quote uses is down or unhappy.
The tests can also fail if you have not installed all the modules
that Finance::Quote depends upon. See the section on dependancies
above.
If you believe you've found a bug, please report it using our
bugtracking system at http://sourceforge.net/bugs/?group_id=4232
or send mail to <finance-quote-devel@lists.sourceforge.net>.
More information?
-----------------
Try visiting the Finance::Quote webpage
at http://finance-quote.sourceforge.net/
Maintainer
----------
Paul Fenwick <pjf@cpan.org>

View File

@@ -1,37 +0,0 @@
ChangeLog
INSTALL
MANIFEST
Makefile.PL
Documentation/FAQ
Documentation/Hackers-Guide
Documentation/License
Documentation/README
Examples/Quote_example.pl
Examples/chkshares.pl
Examples/currency-lookup.pl
Examples/stockdump.pl
lib/Finance/Quote.pm
lib/Finance/Quote/ASX.pm
lib/Finance/Quote/DWS.pm
lib/Finance/Quote/Fidelity.pm
lib/Finance/Quote/Tiaacref.pm
lib/Finance/Quote/Troweprice.pm
lib/Finance/Quote/Trustnet.pm
lib/Finance/Quote/UserAgent.pm
lib/Finance/Quote/VWD.pm
lib/Finance/Quote/Yahoo/Australia.pm
lib/Finance/Quote/Yahoo/Base.pm
lib/Finance/Quote/Yahoo/Europe.pm
lib/Finance/Quote/Yahoo/USA.pm
t/Use.t
t/asx.t
t/currency.t
t/dws.t
t/fidelity.t
t/tiaacref.t
t/troweprice.t
t/trustnet.t
t/vanguard.t
t/vwd.t
t/yahoo.t
t/yahoo_europe.t

View File

@@ -1,11 +0,0 @@
#!/usr/bin/perl -w
use strict;
use ExtUtils::MakeMaker;
WriteMakefile( NAME => "Finance::Quote",
PREREQ_PM => { "LWP::UserAgent" => 0,
"HTTP::Request::Common" => 0,
"HTML::TableExtract" => 0},
VERSION_FROM => "lib/Finance/Quote.pm"
);

View File

@@ -1,807 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote;
require 5.005;
use strict;
use Exporter ();
use Carp;
use Finance::Quote::UserAgent;
use HTTP::Request::Common;
use vars qw/@ISA @EXPORT @EXPORT_OK @EXPORT_TAGS
$VERSION $TIMEOUT %MODULES %METHODS $AUTOLOAD
$YAHOO_CURRENCY_URL $USE_EXPERIMENTAL_UA/;
$YAHOO_CURRENCY_URL = "http://uk.finance.yahoo.com/m5?";
@ISA = qw/Exporter/;
@EXPORT = ();
@EXPORT_OK = qw/yahoo yahoo_europe fidelity troweprice asx tiaacref/;
@EXPORT_TAGS = ( all => [@EXPORT_OK]);
$VERSION = '1.05';
$USE_EXPERIMENTAL_UA = 0;
# Autoload method for obsolete methods. This also allows people to
# call methods that objects export without having to go through fetch.
sub AUTOLOAD {
my $method = $AUTOLOAD;
$method =~ s/.*:://;
# Force the dummy object (and hence default methods) to be loaded.
_dummy();
# If the method we want is in %METHODS, then set up an appropriate
# subroutine for it next time.
if (exists($METHODS{$method})) {
eval qq[sub $method {
my \$this;
if (ref \$_[0]) {
\$this = shift;
}
\$this ||= _dummy();
\$this->fetch("$method",\@_);
}];
carp $@ if $@;
no strict 'refs'; # So we can use &$method
return &$method(@_);
}
carp "$AUTOLOAD does not refer to a known method.";
}
# _load_module (private class method)
# _load_module loads a module(s) and registers its various methods for
# use.
sub _load_modules {
my $class = shift;
my $baseclass = ref $class || $class;
my @modules = @_;
# Go to each module and use them. Also record what methods
# they support and enter them into the %METHODS hash.
foreach my $module (@modules) {
my $modpath = "${baseclass}::${module}";
unless (defined($MODULES{$modpath})) {
# Have to use an eval here because perl doesn't
# like to use strings.
eval "use $modpath;";
carp $@ if $@;
$MODULES{$modpath} = 1;
# Methodhash will continue method-name, function ref
# pairs.
my %methodhash = $modpath->methods;
my %labelhash = $modpath->labels;
# Find the labels that we can do currency conversion
# on.
my $curr_fields_func = $modpath->can("currency_fields")
|| \&default_currency_fields;
my @currency_fields = &$curr_fields_func;
# @currency_fields may contain duplicates.
# This following chunk of code removes them.
my %seen;
@currency_fields=grep {!$seen{$_}++} @currency_fields;
foreach my $method (keys %methodhash) {
push (@{$METHODS{$method}},
{ function => $methodhash{$method},
labels => $labelhash{$method},
currency_fields => \@currency_fields});
}
}
}
}
# =======================================================================
# new (public class method)
#
# Returns a new Finance::Quote object. If methods are asked for, then
# it will load the relevant modules. With no arguments, this function
# loads a default set of methods.
sub new {
my $self = shift;
my $class = ref($self) || $self;
my $this = {};
bless $this, $class;
my @modules = ();
# If there's no argument list, but we have the appropriate
# environment variable set, we'll use that instead.
if ($ENV{FQ_LOAD_QUOTELET} and !@_) {
@_ = split(' ',$ENV{FQ_LOAD_QUOTELET});
}
# If we get an empty new(), or one starting with -defaults,
# then load up the default methods.
if (!@_ or $_[0] eq "-defaults") {
shift if (@_);
# Default modules
@modules = qw/Yahoo::Australia Fidelity ASX Troweprice
Tiaacref Yahoo::USA Yahoo::Europe
DWS VWD Trustnet/;
}
$this->_load_modules(@modules,@_);
$this->{TIMEOUT} = $TIMEOUT if defined($TIMEOUT);
$this->{FAILOVER} = 1;
$this->{REQUIRED} = [];
return $this;
}
# =======================================================================
# _dummy (private function)
#
# _dummy returns a Finance::Quote object. I'd really rather not have
# this, but to maintain backwards compatibility we hold on to it.
{
my $dummy_obj;
sub _dummy {
return $dummy_obj ||= Finance::Quote->new;
}
}
# =======================================================================
# currency (public object method)
#
# currency allows the conversion of one currency to another.
#
# Usage: $quoter->currency("USD","AUD");
# $quoter->currency("15.95 USD","AUD");
#
# undef is returned upon error.
sub currency {
my $this = shift if (ref($_[0]));
$this ||= _dummy();
my ($from, $to) = @_;
return undef unless ($from and $to);
$from =~ s/^\s*(\d*\.?\d*)\s*//;
my $amount = $1 || 1;
# Don't know if these have to be in upper case, but it's
# better to be safe than sorry.
$to = uc($to);
$from = uc($from);
return $amount if ($from eq $to); # Trivial case.
my $ua = $this->user_agent;
my $data = $ua->request(GET "${YAHOO_CURRENCY_URL}s=$from&t=$to")->content;
my ($exchange_rate) = $data =~ m#$from$to=X</a></td><td>1</td><td(?: nowrap)?>[^<]+</td><td>(\d+\.\d+)</td>#;
return undef unless $exchange_rate;
return ($exchange_rate * $amount);
}
# =======================================================================
# set_currency (public object method)
#
# set_currency allows information to be requested in the specified
# currency. If called with no arguments then information is returned
# in the default currency.
#
# Requesting stocks in a particular currency increases the time taken,
# and the likelyhood of failure, as additional operations are required
# to fetch the currency conversion information.
#
# This method should only be called from the quote object unless you
# know what you are doing.
sub set_currency {
my $this = shift if (ref $_[0]);
$this ||= _dummy();
unless (defined($_[0])) {
delete $this->{"currency"};
} else {
$this->{"currency"} = $_[0];
}
}
# default_currency_fields (public method)
#
# This is a list of fields that will be automatically converted during
# currency conversion. If a module provides a currency_fields()
# function then that list will be used instead.
sub default_currency_fields {
return qw/last high low net bid ask close open day_range year_range
eps div cap nav price/;
}
# _convert (private object method)
#
# This function converts between one currency and another. It expects
# to receive a hashref to the information, a reference to a list
# of the stocks to be converted, and a reference to a list of fields
# that conversion should apply to.
{
my %conversion; # Conversion lookup table.
sub _convert {
my $this = shift;
my $info = shift;
my $stocks = shift;
my $convert_fields = shift;
my $new_currency = $this->{"currency"};
# Skip all this unless they actually want conversion.
return unless $new_currency;
foreach my $stock (@$stocks) {
my $currency;
# Skip stocks that don't have a currency.
next unless ($currency = $info->{$stock,"currency"});
# Skip if it's already in the same currency.
next if ($currency eq $new_currency);
# Lookup the currency conversion if we haven't
# already.
unless (exists $conversion{$currency,$new_currency}) {
$conversion{$currency,$new_currency} =
$this->currency($currency,$new_currency);
}
# Make sure we have a reasonable currency conversion.
# If we don't, mark the stock as bad.
unless ($conversion{$currency,$new_currency}) {
$info->{$stock,"success"} = 0;
$info->{$stock,"errormsg"} =
"Currency conversion failed.";
next;
}
# Okay, we have clean data. Convert it. Ideally
# we'd like to just *= entire fields, but
# unfortunately some things (like ranges,
# capitalisation, etc) don't take well to that.
# Hence we pull out any numbers we see, convert
# them, and stick them back in. That's pretty
# yucky, but it works.
foreach my $field (@$convert_fields) {
next unless (defined $info->{$stock,$field});
$info->{$stock,$field} = $this->scale_field($info->{$stock,$field},$conversion{$currency,$new_currency});
}
# Set the new currency.
$info->{$stock,"currency"} = $new_currency;
}
}
}
# =======================================================================
# Helper function that can scale a field. This is useful because it
# handles things like ranges "105.4 - 108.3", and not just straight fields.
#
# The function takes a string or number to scale, and the factor to scale
# it by. For example, scale_field("1023","0.01") would return "10.23".
sub scale_field {
shift if ref $_[0]; # Shift off the object, if there is one.
my ($field, $scale) = @_;
my @chunks = split(/([^0-9.])/,$field);
for (my $i=0; $i < @chunks; $i++) {
next unless $chunks[$i] =~ /\d/;
$chunks[$i] *= $scale;
}
return join("",@chunks);
}
# =======================================================================
# Timeout code. If called on a particular object, then it sets
# the timout for that object only. If called as a class method
# (or as Finance::Quote::timeout) then it sets the default timeout
# for all new objects that will be created.
sub timeout {
if (@_ == 1 or !ref($_[0])) { # Direct or class call.
return $TIMEOUT = $_[0];
}
# Otherwise we were called through an object. Yay.
# Set the timeout in this object only.
my $this = shift;
return $this->{TIMEOUT} = shift;
}
# =======================================================================
# failover (public object method)
#
# This sets/gets whether or not it's acceptable to use failover techniques.
sub failover {
my $this = shift;
my $value = shift;
return $this->{FAILOVER} = $value if (defined($value));
return $this->{FAILOVER};
}
# =======================================================================
# require_labels (public object method)
#
# Require_labels indicates which labels are required for lookups. Only methods
# that have registered all the labels specified in the list passed to
# require_labels() will be called.
#
# require_labels takes a list of required labels. When called with no
# arguments, the require list is cleared.
#
# This method always succeeds.
sub require_labels {
my $this = shift;
my @labels = @_;
$this->{REQUIRED} = \@labels;
return;
}
# _require_test (private object method)
#
# This function takes an array. It returns true if all required
# labels appear in the arrayref. It returns false otherwise.
#
# This function could probably be made more efficient.
sub _require_test {
my $this = shift;
my %available;
@available{@_} = (); # Ooooh, hash-slice. :)
my @required = @{$this->{REQUIRED}};
return 1 unless @required;
for (my $i = 0; $i < @required; $i++) {
return 0 unless exists $available{$required[$i]};
}
return 1;
}
# =======================================================================
# fetch (public object method)
#
# Fetch is a wonderful generic fetcher. It takes a method and stuff to
# fetch. It's a nicer interface for when you have a list of stocks with
# different sources which you wish to deal with.
sub fetch {
my $this = shift if ref ($_[0]);
$this ||= _dummy();
my $method = lc(shift);
my @stocks = @_;
unless (exists $METHODS{$method}) {
carp "Undefined fetch-method $method passed to ".
"Finance::Quote::fetch";
return;
}
# Failover code. This steps through all availabe methods while
# we still have failed stocks to look-up. This loop only
# runs a single time unless FAILOVER is defined.
my %returnhash = ();
foreach my $methodinfo (@{$METHODS{$method}}) {
my $funcref = $methodinfo->{"function"};
next unless $this->_require_test(@{$methodinfo->{"labels"}});
my @failed_stocks = ();
%returnhash = (%returnhash,&$funcref($this,@stocks));
foreach my $stock (@stocks) {
push(@failed_stocks,$stock)
unless ($returnhash{$stock,"success"});
}
$this->_convert(\%returnhash,\@stocks,
$methodinfo->{"currency_fields"});
last unless $this->{FAILOVER};
last unless @failed_stocks;
@stocks = @failed_stocks;
}
return wantarray() ? %returnhash : \%returnhash;
}
# =======================================================================
# user_agent (public object method)
#
# Returns a LWP::UserAgent which conforms to the relevant timeouts,
# proxies, and other settings on the particular Finance::Quote object.
#
# This function is mainly intended to be used by the modules that we load,
# but it can be used by the application to directly play with the
# user-agent settings.
sub user_agent {
my $this = shift;
return $this->{UserAgent} if $this->{UserAgent};
my $ua;
if ($USE_EXPERIMENTAL_UA) {
$ua = Finance::Quote::UserAgent->new;
} else {
$ua = LWP::UserAgent->new;
}
$ua->timeout($this->{TIMEOUT}) if defined($this->{TIMEOUT});
$ua->env_proxy;
$this->{UserAgent} = $ua;
return $ua;
}
# =======================================================================
# parse_csv (public object method)
#
# Grabbed from the Perl Cookbook. Parsing csv isn't as simple as you thought!
#
sub parse_csv
{
shift if (ref $_[0]); # Shift off the object if we have one.
my $text = shift; # record containing comma-separated values
my @new = ();
push(@new, $+) while $text =~ m{
# the first part groups the phrase inside the quotes.
# see explanation of this pattern in MRE
"([^\"\\]*(?:\\.[^\"\\]*)*)",?
| ([^,]+),?
| ,
}gx;
push(@new, undef) if substr($text, -1,1) eq ',';
return @new; # list of values that were comma-separated
}
# Dummy destroy function to avoid AUTOLOAD catching it.
sub DESTROY { return; }
1;
__END__
=head1 NAME
Finance::Quote - Get stock and mutual fund quotes from various exchanges
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
$q->timeout(60);
$conversion_rate = $q->currency("AUD","USD");
$q->set_currency("EUR"); # Return all info in Euros.
$q->require_labels(qw/price date high low volume/);
$q->failover(1); # Set failover support (on by default).
%quotes = $q->fetch("nasdaq",@stocks);
$hashref = $q->fetch("nyse",@stocks);
=head1 DESCRIPTION
This module gets stock quotes from various internet sources, including
Yahoo! Finance, Fidelity Investments, and the Australian Stock Exchange.
There are two methods of using this module -- a functional interface
that is depreciated, and an object-orientated method that provides
greater flexibility and stability.
With the exception of straight currency exchange rates, all information
is returned as a two-dimensional hash (or a reference to such a hash,
if called in a scalar context). For example:
%info = $q->fetch("australia","CML");
print "The price of CML is ".$info{"CML","price"};
The first part of the hash (eg, "CML") is referred to as the stock.
The second part (in this case, "price") is referred to as the label.
=head2 LABELS
When information about a stock is returned, the following standard labels
may be used. Some custom-written modules may use labels not mentioned
here. If you wish to be certain that you obtain a certain set of labels
for a given stock, you can specify that using require_labels().
name Company or Mutual Fund Name
last Last Price
high Highest trade today
low Lowest trade today
date Last Trade Date (MM/DD/YY format)
time Last Trade Time
net Net Change
p_change Percent Change from previous day's close
volume Volume
avg_vol Average Daily Vol
bid Bid
ask Ask
close Previous Close
open Today's Open
day_range Day's Range
year_range 52-Week Range
eps Earnings per Share
pe P/E Ratio
div_date Dividend Pay Date
div Dividend per Share
div_yield Dividend Yield
cap Market Capitalization
ex_div Ex-Dividend Date.
nav Net Asset Value
yield Yield (usually 30 day avg)
exchange The exchange the information was obtained from.
success Did the stock successfully return information? (true/false)
errormsg If success is false, this field may contain the reason why.
method The module (as could be passed to fetch) which found
this information.
If all stock lookups fail (possibly because of a failed connection) then
the empty list may be returned, or undef in a scalar context.
=head1 AVAILABLE METHODS
=head2 NEW
my $q = Finance::Quote->new;
my $q = Finance::Quote->new("ASX");
my $q = Finance::Quote->new("-defaults", "CustomModule");
With no arguents, this creates a new Finance::Quote object
with the default methods. If the environment variable
FQ_LOAD_QUOTELETS is set, then the contents of FQ_LOAD_QUOTELETS
(split on whitespace) will be used as the argument list. This allows
users to load their own custom modules without having to change
existing code. If you do not want users to be able to load their own
modules at run-time, pass an explicit argumetn to ->new() (usually
"-defaults").
When new() is passed one or more arguments, an object is created with
only the specified modules loaded. If the first argument is
"-defaults", then the default modules will be loaded first, followed
by any other specified modules.
Note that the FQ_LOAD_QUOTELETS environment variable must begin
with "-defaults" if you wish the default modules to be loaded.
Any modules specified will automatically be looked for in the
Finance::Quote:: module-space. Hence,
Finance::Quote->new("ASX") will load the module Finance::Quote::ASX.
Please read the Finance::Quote hacker's guide for information
on how to create new modules for Finance::Quote.
=head2 FETCH
my %stocks = $q->fetch("usa","IBM","MSFT","LNUX");
my $hashref = $q->fetch("usa","IBM","MSFT","LNUX");
Fetch takes an exchange as its first argument. The second and remaining
arguments are treated as stock-names. In the standard Finance::Quote
distribution, the following exchanges are recognised:
australia Australan Stock Exchange
dwsfunds Deutsche Bank Gruppe funds
fidelity Fidelity Investments
tiaacref TIAA-CREF
troweprice T. Rowe Price
europe European Markets
canada Canadian Markets
usa USA Markets
nyse New York Stock Exchange
nasdaq NASDAQ
uk_unit_trusts UK Unit Trusts
vanguard Vanguard Investments
vwd Vereinigte Wirtschaftsdienste GmbH
When called in an array context, a hash is returned. In a scalar
context, a reference to a hash will be returned. The structure
of this hash is described earlier in this document.
The fetch method automatically arranges for failover support and
currency conversion if requested.
If you wish to fetch information from only one particular source,
then consult the documentation of that sub-module for further
information.
=head2 CURRENCY
$conversion_rate = $q->currency("USD","AUD");
The currency method takes two arguments, and returns a conversion rate
that can be used to convert from the first currency into the second.
In the example above, we've requested the factor that would convert
US dollars into Australian dollars.
The currency method will return a false value if a given currency
conversion cannot be fetched.
At the moment, currency rates are fetched from Yahoo!, and the
information returned is governed by Yahoo!'s terms and conditions.
See Finance::Quote::Yahoo for more information.
=head2 SET_CURRENCY
$q->set_currency("FRF"); # Get results in French Francs.
The set_currency method can be used to request that all information be
returned in the specified currency. Note that this increases the
chance stock-lookup failure, as remote requests must be made to fetch
both the stock information and the currency rates. In order to
improve reliability and speed performance, currency conversion rates
are cached and are assumed not to change for the duration of the
Finance::Quote object.
At this time, currency conversions are only looked up using Yahoo!'s
services, and hence information obtained with automatic currency
conversion is bound by Yahoo!'s terms and conditions.
=head2 FAILOVER
$q->failover(1); # Set automatic failover support.
$q->failover(0); # Disable failover support.
The failover method takes a single argument which either sets (if
true) or unsets (if false) automatic failover support. If automatic
failover support is enabled (default) then multiple information
sources will be tried if one or more sources fail to return the
requested information. Failover support will significantly increase
the time spent looking for a non-existant stock.
If the failover method is called with no arguments, or with an
undefined argument, it will return the current failover state
(true/false).
=head2 USER_AGENT
my $ua = $q->user_agent;
The user_agent method returns the LWP::UserAgent object that
Finance::Quote and its helpers use. Normally this would not
be useful to an application, however it is possible to modify
the user-agent directly using this method:
$q->user_agent->timeout(10); # Set the timeout directly.
=head2 SCALE_FIELD
my $pounds = $q->scale_field($item_in_pence,0.01);
The scale_field() function is a helper that can scale complex fields such
as ranges (eg, "102.5 - 103.8") and other fields where the numbers should
be scaled but any surrounding text preserved. It's most useful in writing
new Finance::Quote modules where you may retrieve information in a
non-ISO4217 unit (such as cents) and would like to scale it to a more
useful unit (like dollars).
=head1 ENVIRONMENT
Finance::Quote respects all environment that your installed
version of LWP::UserAgent respects. Most importantly, it
respects the http_proxy environment variable.
=head1 BUGS
There are no ways for a user to define a failover list.
The two-dimensional hash is a somewhat unwieldly method of passing
around information when compared to references. A future release
is planned that will allow for information to be returned in a
more flexible $hash{$stock}{$label} style format.
There is no way to override the default behaviour to cache currency
conversion rates.
=head1 COPYRIGHT
Copyright 1998, Dj Padzensky
Copyright 1998, 1999 Linas Vepstas
Copyright 2000, Yannick LE NY (update for Yahoo Europe and YahooQuote)
Copyright 2000, Paul Fenwick (updates for ASX, maintainence and release)
Copyright 2000, Brent Neal (update for TIAA-CREF)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
Currency information fetched through this module is bound by
Yahoo!'s terms and conditons.
Other copyrights and conditions may apply to data fetched through this
module. Please refer to the sub-modules for further information.
=head1 AUTHORS
Dj Padzensky (C<djpadz@padz.net>), PadzNet, Inc.
Linas Vepstas (C<linas@linas.org>)
Yannick LE NY (C<y-le-ny@ifrance.com>)
Paul Fenwick (C<pjf@schools.net.au>)
Brent Neal (C<brentn@users.sourceforge.net>)
Volker Stuerzl (C<volker.stuerzl@gmx.de>)
Keith Refson (C<Keith.Refson#earth.ox.ac.uk>)
The Finance::Quote home page can be found at
http://finance-quote.sourceforge.net/
The Finance::YahooQuote home page can be found at
http://www.padz.net/~djpadz/YahooQuote/
The GnuCash home page can be found at
http://www.gnucash.org/
=head1 SEE ALSO
Finance::Quote::Yahoo, Finance::Quote::ASX, Finance::Quote::Fidelity,
Finance::Quote::Tiaacref, Finance::Quote::Troweprice, LWP::UserAgent,
Finance::Quote::DWS, Finance::Quote::VWD, Finance::Quote::Trustnet
You should have also received the Finance::Quote hacker's guide with
this package. Please read it if you are interested in adding extra
methods to this package. The hacker's guide can also be found
on the Finance::Quote website, http://finance-quote.sourceforge.net/
=cut

View File

@@ -1,227 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@Acpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
require 5.005;
use strict;
package Finance::Quote::ASX;
use HTTP::Request::Common;
use LWP::UserAgent;
use vars qw/$ASX_URL $VERSION/;
$VERSION = "1.02";
$ASX_URL = 'http://www.asx.com.au/nd50/nd_ISAPI_50.dll/asx/markets/EquitySearchResults.jsp?method=post&template=F1001&ASXCodes=';
sub methods {return (australia => \&asx,asx => \&asx)}
{
my @labels = qw/name last p_change bid offer high low volume
price method exchange/;
sub labels { return (australia => \@labels,
asx => \@labels); }
}
# Australian Stock Exchange (ASX)
# The ASX provides free delayed quotes through their webpage.
#
# Maintainer of this section is Paul Fenwick <pjf@cpan.org>
sub asx {
my $quoter = shift;
my @stocks = @_;
return unless @stocks;
my %info;
my $ua = $quoter->user_agent;
my $response = $ua->request(GET $ASX_URL.join("%20",@stocks));
unless ($response->is_success) {
foreach my $stock (@stocks) {
$info{$stock,"success"} = 0;
$info{$stock,"errormsg"} = "HTTP session failed";
}
return wantarray() ? %info : \%info;
}
my $reply = $response->content;
# These first two steps aren't really needed, but are done for
# safety.
# Remove the bottom part of the page.
$reply =~ s#</table>\s*\n<table>.*$##s;
# Remove top of page.
$reply =~ s#.*Chart</font></a></td></tr><tr><td nowrap valign=top>##s;
# Grab the values
my @values;
while ($reply =~ m#<font size='2' face='Arial' color='\#000051'>([^<]*).*?</Font>#g) {
push @values, $1;
}
if (@values % 13) { # Wrong number of fields? Damn!
warn "Bad number of fields returned from ASX website in ".
"Finance::Quote::ASX. Aborting query.\n";
foreach my $stock (@stocks) {
$info{$stock,"success"} = 0;
$info{$stock,"errormsg"} = "ASX website corrupted.";
}
return %info if wantarray;
return \%info;
}
# Go through all the values and pack them into our structure.
# We rely upon the particular ordering of fields at the ASX,
# so this is a little dangerous.
while (@values) {
my $stock = shift @values;
$stock =~ s/&nbsp;//; # Remove guff.
foreach my $label (qw/name last p_change bid offer open
high low volume JUNK JUNK JUNK/) {
my $value = shift @values;
next if ($label eq "JUNK");
# Clean the value.
$value =~ tr/$,%//d;
$value =~ s/&nbsp;//;
$info{$stock,$label} = $value;
}
# If that stock does not exist, it will have a empty
# string for all the fields. The "last" price should
# always be defined (even if zero), if we see an empty
# string here then we know we've found a bogus stock.
if ($info{$stock,'last'} eq '') {
$info{$stock,'success'} = 0;
$info{$stock,'errormsg'}="Stock does not exist on ASX.";
next;
}
# The ASX returns zeros for a number of things if there
# has been no trading. This not only looks silly, but
# can break things later. "correct" zero'd data.
foreach my $label (qw/open high low/) {
if ($info{$stock,$label} == 0) {
$info{$stock,$label} = $info{$stock,"last"};
}
}
# We get a dollar plus/minus change, rather than a
# percentage change, so we convert this into a
# percentage change, as required. We should never have
# zero opening price, but if we do warn about it.
if ($info{$stock,"open"} == 0) {
warn "Zero opening price in p_change calcuation for ".
"stock $stock. P_change set to zero.";
$info{$stock,"p_change"} = 0;
} else {
$info{$stock,"p_change"} = sprintf("%.2f",
($info{$stock,"p_change"}*100)/
$info{$stock,"open"});
}
# Australian indexes all begin with X, so don't tag them
# as having currency info.
$info{$stock, "currency"} = "AUD" unless ($stock =~ /^X/);
$info{$stock, "method"} = "asx";
$info{$stock, "exchange"} = "Australian Stock Exchange";
$info{$stock, "price"} = $info{$stock,"last"};
$info{$stock, "success"} = 1;
}
# All done.
return %info if wantarray;
return \%info;
}
1;
=head1 NAME
Finance::Quote::ASX - Obtain quotes from the Australian Stock Exchange.
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%stockinfo = $q->fetch("asx","BHP"); # Only query ASX.
%stockinfo = $q->fetch("australia","BHP"); # Failover to other sources OK.
=head1 DESCRIPTION
This module obtains information from the Australian Stock Exchange
http://www.asx.com.au/. All Australian stocks and indicies are
available. Indexes start with the letter 'X'. For example, the
All Ordinaries is "XAO".
This module is loaded by default on a Finance::Quote object. It's
also possible to load it explicity by placing "ASX" in the argument
list to Finance::Quote->new().
This module provides both the "asx" and "australia" fetch methods.
Please use the "australia" fetch method if you wish to have failover
with other sources for Australian stocks (such as Yahoo). Using
the "asx" method will guarantee that your information only comes
from the Australian Stock Exchange.
Information returned by this module is governed by the Australian
Stock Exchange's terms and conditions.
=head1 LABELS RETURNED
The following labels may be returned by Finance::Quote::ASX:
date, bid, ask, open, high, low, last, close, p_change, volume,
and price.
=head1 SEE ALSO
Australian Stock Exchange, http://www.asx.com.au/
Finance::Quote::Yahoo::Australia.
=cut

View File

@@ -1,184 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@Acpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
# Copyright (C) 2000, Volker Stuerzl <volker.stuerzl@gmx.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
#
# $Id$
package Finance::Quote::DWS;
require 5.005;
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use vars qw/$VERSION/;
$VERSION = '1.00';
sub methods { return (dwsfunds => \&dwsfunds); }
sub labels { return (dwsfunds => [qw/exchange name date price method/]); }
# =======================================================================
# The dwsfunds routine gets quotes of DWS funds (Deutsche Bank Gruppe)
# On their website DWS provides a csv file in the format
# symbol1,price1,date1
# symbol2,price2,date2
# ...
#
# This subroutine was written by Volker Stuerzl <volker.stuerzl@gmx.de>
sub dwsfunds
{
my $quoter = shift;
my @funds = @_;
return unless @funds;
my $ua = $quoter->user_agent;
my (%fundhash, @q, @date, %info);
# create hash of all funds requested
foreach my $fund (@funds)
{
$fundhash{$fund} = 0;
}
# get csv data
my $response = $ua->request(GET &dwsurl);
if ($response->is_success)
{
# process csv data
foreach (split('\015?\012',$response->content))
{
@q = $quoter->parse_csv($_) or next;
if (exists $fundhash{$q[0]})
{
$fundhash{$q[0]} = 1;
# convert price from german (0,00) to US format (0.00)
$q[1] =~ s/,/\./;
# convert date from german (dd.mm.yyyy) to US format (mm/dd/yyyy)
@date = split /\./, $q[2];
$q[2] = $date[1]."/".$date[0]."/".$date[2];
$info{$q[0], "exchange"} = "DWS";
$info{$q[0], "name"} = $q[0];
$info{$q[0], "price"} = $q[1];
$info{$q[0], "last"} = $q[1];
$info{$q[0], "date"} = $q[2];
$info{$q[0], "method"} = "dwsfunds";
$info{$q[0], "currency"} = "EUR";
$info{$q[0], "success"} = 1;
}
}
# check to make sure a value was returned for every fund requested
foreach my $fund (keys %fundhash)
{
if ($fundhash{$fund} == 0)
{
$info{$fund, "success"} = 0;
$info{$fund, "errormsg"} = "No data returned";
}
}
}
else
{
foreach my $fund (@funds)
{
$info{$fund, "success"} = 0;
$info{$fund, "errormsg"} = "HTTP error";
}
}
return wantarray() ? %info : \%info;
}
# DWS provides csv files containing the prices of all their funds for the 5
# most recent business days. The file names are ordered numerically, that is
# dws1.csv contains prices for monday, dws2.csv those for tuesday and so on.
# The files are updated until 6:00pm on every business day. Before that time
# the file of the previous day has to be used.
sub dwsurl
{
# Since DWS is located at Frankfurt/Germany, this code only works for
# central european time zone
my @time = localtime;
my $hour = $time[2];
my $wday = $time[6];
# during weekend use file of friday
if ($wday == 6 || $wday == 0)
{
$wday = 5;
}
# on business days before 6:00pm use file of previous day
else
{
if ($hour < 18)
{
$wday--;
if ($wday == 0) { $wday = 5; };
}
}
return "http://www.dws.de/aktuell/dws".$wday.".csv";
}
1;
=head1 NAME
Finance::Quote::DWS - Obtain quotes from DWS (Deutsche Bank Gruppe).
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%stockinfo = $q->fetch("dwsfunds","847402");
=head1 DESCRIPTION
This module obtains information about DWS managed funds.
Information returned by this module is governed by DWS's terms
and conditions.
=head1 LABELS RETURNED
The following labels may be returned by Finance::Quote::DWS:
exchange, name, date, price, last.
=head1 SEE ALSO
DWS (Deutsche Bank Gruppe), http://www.dws.de/
=cut

View File

@@ -1,300 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote::Fidelity;
require 5.005;
use strict;
use vars qw/$FIDELITY_GANDI_URL $FIDELITY_GROWTH_URL $FIDELITY_CORPBOND_URL
$FIDELITY_GLBND_URL $FIDELITY_MM_URL $FIDELITY_ASSET_URL
$VERSION/;
use LWP::UserAgent;
use HTTP::Request::Common;
$VERSION = '1.00';
$FIDELITY_GANDI_URL = ("http://personal441.fidelity.com/gen/prices/gandi.csv");
$FIDELITY_GROWTH_URL = ("http://personal441.fidelity.com/gen/prices/growth.csv");
$FIDELITY_CORPBOND_URL = ("http://personal441.fidelity.com/gen/prices/corpbond.csv");
$FIDELITY_GLBND_URL = ("http://personal441.fidelity.com/gen/prices/glbnd.csv");
$FIDELITY_MM_URL = ("http://personal441.fidelity.com/gen/prices/mm.csv");
$FIDELITY_ASSET_URL = ("http://personal441.fidelity.com/gen/prices/asset.csv");
sub methods {return (fidelity => \&fidelity,
fidelity_direct => \&fidelity);}
sub labels { return (fidelity=>[qw/exchange name number nav change ask
date yield price method/]); }
# =======================================================================
# the fidelity routine gets quotes from fidelity investments
#
sub fidelity
{
my $quoter = shift;
my @symbols = @_;
return unless @symbols;
my(%aa,%cc,$sym, $k);
# Build a small hash of symbols people want, because it provides a
# quick and easy way to only return desired symbols.
my %symbolhash;
@symbolhash{@symbols} = map(1,@symbols);
# rather irritatingly, fidelity sorts its funds into different groups.
# as a result, the fetch that we need to do depends on the group.
my @gandi = ("FBALX", "FCVSX", "FEQIX", "FEQTX", "FFIDX", "FGRIX",
"FIUIX", "FPURX", "FRESX", );
my @growth = ("FBGRX", "FCNTX", "FCONX", "FDCAX", "FDEGX", "FDEQX",
"FDFFX", "FDGFX", "FDGRX", "FDSCX", "FDSSX", "FDVLX",
"FEXPX", "FFTYX", "FLCSX", "FLPSX", "FMAGX", "FMCSX",
"FMILX", "FOCPX", "FSLCX", "FSLSX", "FTQGX", "FTRNX",
"FTXMX", );
my @corpbond = ("FAGIX", "SPHIX", "FTHRX", "FBNDX", "FSHBX", "FSIBX",
"FTBDX", "FSICX", "FTTAX", "FTTBX", "FTARX", );
my @glbnd = ("FGBDX", "FNMIX");
my @mm = ("FDRXX", "FDTXX", "FGMXX", "FRTXX", "SPRXX", "SPAXX",
"FDLXX", "FGRXX",);
my @asset = ("FASMX", "FASGX", "FASIX", );
my (%agandi, %agrowth, %acorpbond, %aglbnd, %amm, %aasset);
my $dgandi=0;
my $dgrowth=0;
my $dcorpbond=0;
my $dglbnd=0;
my $dmm=0;
my $dasset=0;
for (@gandi) { $agandi{$_} ++; }
for (@growth) { $agrowth{$_} ++; }
for (@corpbond) { $acorpbond{$_} ++; }
for (@glbnd) { $aglbnd{$_} ++; }
for (@mm) { $amm{$_} ++; }
for (@asset) { $aasset{$_} ++; }
# the fidelity pages are comma-separated-values (csv's)
# there are two basic layouts, with, and without prices
for (@symbols) {
if ($agandi {$_} ) {
if (0 == $dgandi ) {
%cc = &_fidelity_nav ($quoter, $FIDELITY_GANDI_URL,\%symbolhash);
$dgandi = 1;
foreach $k (keys %cc) { $aa{$k} = $cc{$k}; }
}
}
if ($agrowth {$_} ) {
if (0 == $dgrowth ) {
%cc = &_fidelity_nav ($quoter, $FIDELITY_GROWTH_URL,\%symbolhash);
$dgrowth = 1;
foreach $k (keys %cc) { $aa{$k} = $cc{$k}; }
}
}
if ($acorpbond {$_} ) {
if (0 == $dcorpbond ) {
%cc = &_fidelity_nav ($quoter, $FIDELITY_CORPBOND_URL,\%symbolhash);
$dcorpbond = 1;
foreach $k (keys %cc) { $aa{$k} = $cc{$k}; }
}
}
if ($aglbnd {$_} ) {
if (0 == $dglbnd ) {
%cc = &_fidelity_nav ($quoter, $FIDELITY_GLBND_URL,\%symbolhash);
$dglbnd = 1;
foreach $k (keys %cc) { $aa{$k} = $cc{$k}; }
}
}
if ($amm {$_} ) {
if (0 == $dmm ) {
%cc = &_fidelity_mm ($quoter, $FIDELITY_MM_URL,\%symbolhash);
$dmm = 1;
foreach $k (keys %cc) { $aa{$k} = $cc{$k}; }
}
}
if ($aasset {$_} ) {
if (0 == $dasset ) {
%cc = &_fidelity_nav ($quoter, $FIDELITY_ASSET_URL,\%symbolhash);
$dasset = 1;
foreach $k (keys %cc) { $aa{$k} = $cc{$k}; }
}
}
}
return %aa if wantarray;
return \%aa;
}
# =======================================================================
# Private function used by fidelity.
sub _fidelity_nav
{
my $quoter = shift;
my $url = shift;
my $symbolhash = shift;
my(@q,%aa,$ua,$sym, $dayte);
my %days = ('Monday','Mon','Tuesday','Tue','Wednesday','Wed',
'Thursday','Thu','Friday','Fri','Saturday','Sat',
'Sunday','Sun');
# for Fidelity, we get them all.
$ua = $quoter->user_agent;
my $reply = $ua->request(GET $url);
return unless ($reply->is_success);
foreach (split('\015?\012',$reply->content))
{
@q = $quoter->parse_csv($_) or next;
$sym = $q[2] or next;
$sym =~ s/^ +//;
# Skip symbols we didn't ask for.
next unless (defined($symbolhash->{$sym}));
# extract the date which is usually on the second line fo the file.
if (! defined ($dayte)) {
if ($days {$q[0]} ) {
($dayte = $q[1]) =~ s/^ +//;
}
}
if ($q[7]) {
$aa {$sym, "exchange"} = "Fidelity"; # Fidelity
$aa {$sym, "method"} = "fidelity_direct";
($aa {$sym, "name"} = $q[0]) =~ s/^ +//;
$aa {$sym, "name"} =~ s/$ +//;
($aa {$sym, "number"} = $q[1]) =~ s/^ +//;
($aa {$sym, "nav"} = $q[3]) =~ s/^ +//;
($aa {$sym, "change"} = $q[4]) =~ s/^ +//;
($aa {$sym, "ask"} = $q[7]) =~ s/^ +//;
$aa {$sym, "date"} = $dayte;
$aa {$sym, "price"} = $aa{$sym, "nav"};
$aa {$sym, "success"} = 1;
$aa {$sym, "currency"} = "USD";
}
}
return %aa;
}
# =======================================================================
# Private function used by fidelity.
sub _fidelity_mm
{
my $quoter = shift;
my $url = shift;
my $symbolhash = shift;
my(@q,%aa,$ua,$sym, $dayte);
my %days = ('Monday','Mon','Tuesday','Tue','Wednesday','Wed',
'Thursday','Thu','Friday','Fri','Saturday','Sat',
'Sunday','Sun');
# for Fidelity, we get them all.
$ua = $quoter->user_agent;
my $reply = $ua->request(GET $url);
return unless ($reply->is_success);
foreach (split('\015?\012',$reply->content))
{
@q = $quoter->parse_csv($_) or next;
$sym = $q[2] or next;
$sym =~ s/^ +//;
# Skip symbols we didn't ask for.
next unless (defined($symbolhash->{$sym}));
# extract the date which is usually on the second line fo the file.
if (! defined ($dayte)) {
if ($days {$q[0]} ) {
($dayte = $q[1]) =~ s/^ +//;
}
}
if ($q[3]) {
$sym =~ s/^ +//;
$aa {$sym, "exchange"} = "Fidelity"; # Fidelity
($aa {$sym, "name"} = $q[0]) =~ s/^ +//;
$aa {$sym, "name"} =~ s/$ +//;
($aa {$sym, "number"} = $q[1]) =~ s/^ +//;
($aa {$sym, "yield"} = $q[3]) =~ s/^ +//;
$aa {$sym, "date"} = $dayte;
$aa {$sym, "price"} = $aa{$sym, "yield"};
$aa {$sym, "success"} = 1;
$aa {$sym, "currency"} = "USD";
}
}
return %aa;
}
1;
=head1 NAME
Finance::Quote::Fidelity - Obtain information from Fidelity Investments.
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%info = Finance::Quote->fetch("fidelity","FBGRX");
%info = Finance::Quote->fetch("fidelity_direct","FBGRX");
=head1 DESCRIPTION
This module obtains information from Fidelity Investments,
http://www.fidelity.com/. This module is loaded by default on
the Finance::Quote object. It is also possible to load this
module explicitly by passing "Fidelity" as one of
Finance::Quote->new()'s parameters.
The "fidelity" fetch method may make use of failover modules.
The "fidelity_direct" method will only obtain information
directly from Fidelity.
Information returned by this module is governed by Fidelity
Investment's terms and conditions.
=head1 LABELS RETURNED
The following labels may be returned by Finance::Quote::Fidelity:
exchange, name, number, nav, change, ask, date, yield, price.
=head1 SEE ALSO
Fidelity Investments, http://www.fidelity.com/
Finance::Quote::Yahoo::USA;
=cut

View File

@@ -1,211 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote::Tiaacref;
require 5.005;
use strict;
use vars qw($VERSION $TIAACREF_URL %tiaacref_ids);
use LWP::UserAgent;
use HTTP::Request::Common;
use Carp;
$VERSION = '1.00';
# URLs of where to obtain information.
$TIAACREF_URL = ("http://www.tiaa-cref.org/financials/selection/ann-select.cgi?");
sub methods { return (tiaacref=>\&tiaacref); }
sub labels { return (tiaacref => [qw/method symbol exchange name date nav price/]); }
# =======================================================================
# TIAA-CREF Annuities are not listed on any exchange, unlike their mutual funds
# TIAA-CREF provides unit values via a cgi on their website. The cgi returns
# a csv file in the format
# bogus_symbol1,price1,date1
# bogus_symbol2,price2,date2
# ..etc.
# where bogus_symbol takes on the following values for the various annuities:
#
#Stock: CREFstok
#Money Market: CREFmony
#Equity Index: CREFequi
#Inf-Linked Bond: CREFinfb
#Bond Market: CREFbond
#Social Choice: CREFsoci
#Global Equities: CREFglob
#Growth: CREFgrow
#TIAA Real Estate: TIAAreal
#PA Stock Index: TIAAsndx
#PA Select Stock: TIAAsele
#
# This subroutine was written by Brent Neal <brentn@users.sourceforge.net>
#
# TODO:
#
# The TIAA-CREF cgi allows you to specify the exact dates for which to retrieve
# price data. That functionality could be worked into this subroutine.
# Currently, we only grab the most recent price data.
#
sub tiaacref
{
my $quoter = shift;
if (! %tiaacref_ids ) { #build a name hash for the annuities (once only)
$tiaacref_ids{"CREFstok"} = "CREF Stock";
$tiaacref_ids{"CREFmony"} = "CREF Money Market";
$tiaacref_ids{"CREFequi"} = "CREF Equity Index";
$tiaacref_ids{"CREFinfb"} = "CREF Inflation-Linked Bond";
$tiaacref_ids{"CREFbond"} = "CREF Bond Market";
$tiaacref_ids{"CREFsoci"} = "CREF Social Choice";
$tiaacref_ids{"CREFglob"} = "CREF Global Equities";
$tiaacref_ids{"CREFgrow"} = "CREF Growth";
$tiaacref_ids{"TIAAreal"} = "TIAA Real Estate";
$tiaacref_ids{"TIAAsndx"} = "TIAA Teachers Personal Annuity Stock Index";
$tiaacref_ids{"TIAAsele"} = "TIAA Teachers Personal Annuity Select Stock";
}
my(@funds) = @_;
return unless @funds;
my(@line); #holds the return from parse_csv
my(%info);
my(%check); #holds success value if data returned
my($ua,$url); #useragent and target url
my($reply); #the reply from TIAA-CREF's cgi
$url = $TIAACREF_URL;
foreach my $fund (@funds) {
if ($tiaacref_ids{$fund}) {
$url .= $fund . "=yes&";
$check{$fund} = 0;
} else {
$info{$fund,"success"} = 0;
$info{$fund,"errormsg"} = "Bad symbol";
}
}
$url .= "selected=1";
$ua = $quoter->user_agent;
$reply = $ua->request(GET $url);
if ($reply ->is_success) {
foreach (split('\012',$reply->content) ){
@line = $quoter->parse_csv($_);
if (exists $check{$line[0]}) { #did we ask for this data?
$info{$line[0],"symbol"} = $line[0]; #in case the caller needs this in the hash
$info{$line[0],"exchange"} = "TIAA-CREF";
$info{$line[0],"name"} = $tiaacref_ids{$line[0]};
$info{$line[0],"date"} = $line[2];
$info{$line[0],"nav"} = $line[1];
$info{$line[0],"price"} = $info{$line[0],"nav"};
$info{$line[0],"success"} = 1; #this contains good data,
#beyond a reasonable doubt
$info{$line[0],"currency"} = "USD";
$info{$line[0],"method"} = "tiaacref";
$info{$line[0],"exchange"} = "TIAA-CREF";
$check{$line[0]} = 1;
} else {
$info{$line[0],"success"} = 0;
$info{$line[0],"errormsg"} = "Bad data returned";
}
}
} else {
foreach $_ (@funds) {
$info{$_,"success"} = 0;
$info{$_,"errormsg"} = "HTTP error";
} # foreach
} #if $reply->is_success else
#now check to make sure a value was returned for every symbol asked for
foreach my $k (keys %check) {
if ($check{$k} == 0) {
$info{$k,"success"} = 0;
$info{$k,"errormsg"} = "No data returned";
}
}
return %info if wantarray;
return \%info;
}
1;
=head1 NAME
Finance::Quote::Tiaacref - Obtain quote from TIAA-CREF.
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%stockinfo = $q->fetch("tiaacref","TIAAreal");
=head1 DESCRIPTION
This module obtains information about TIAA-CREF managed funds.
The following symbols can be used:
Stock: CREFstok
Money Market: CREFmony
Equity Index: CREFequi
Inf-Linked Bond: CREFinfb
Bond Market: CREFbond
Social Choice: CREFsoci
Global Equities: CREFglob
Growth: CREFgrow
TIAA Real Estate: TIAAreal
PA Stock Index: TIAAsndx
PA Select Stock: TIAAsele
This module is loaded by default on a Finance::Quote object. It's
also possible to load it explicitly by passing "Tiaacref" in to the
argument argument list of Finance::Quote->new().
Information returned by this module is governed by TIAA-CREF's terms
and conditions.
=head1 LABELS RETURNED
The following labels may be returned by Finance::Quote::Tiaacref:
symbol, exchange, name, date, nav, price.
=head1 SEE ALSO
TIAA-CREF, http://www.tiaa-cref.org/
=cut

View File

@@ -1,124 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote::Troweprice;
require 5.005;
use strict;
use vars qw($VERSION $TROWEPRICE_URL);
use LWP::UserAgent;
use HTTP::Request::Common;
use Carp;
$VERSION = '1.00';
# URLs of where to obtain information.
$TROWEPRICE_URL = ("http://www.troweprice.com/funds/prices.csv");
sub methods { return (troweprice => \&troweprice); }
sub labels { return (troweprice => [qw/method exchange name nav date price/]); }
# =======================================================================
sub troweprice
{
my $quoter = shift;
my(@q,%aa,$ua,$url,$sym);
# for T Rowe Price, we get them all.
$url = $TROWEPRICE_URL;
$ua = $quoter->user_agent;
my $reply = $ua->request(GET $url);
return unless ($reply->is_success);
foreach (split('\015?\012',$reply->content))
{
@q = $quoter->parse_csv($_);
# extract the date which is usually on the second line fo the file.
($sym = $q[0]) =~ s/^ +//;
if ($sym) {
$aa {$sym, "exchange"} = "T. Rowe Price"; # TRP
$aa {$sym, "method"} = "troweprice";
# ($aa {$sym, "name"} = $q[0]) =~ s/^ +//;
$aa {$sym, "name"} = $sym; # no name supplied ...
$aa {$sym, "nav"} = $q[1];
$aa {$sym, "date"} = $q[2];
$aa {$sym, "price"} = $aa{$sym,"nav"};
$aa {$sym, "success"} = 1;
$aa {$sym, "currency"} = "USD";
} else {
$aa {$sym, "success"} = 0;
$aa {$sym, "errormsg"} = "Stock lookup failed.";
}
}
return %aa if wantarray;
return \%aa;
}
1;
=head1 NAME
Finance::Quote::Troweprice - Obtain quotes from T. Rowe Price
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%stockinfo = $q->fetch("troweprice","PRFDX"); # Can failover to other methods
%stockinfo = $q->fetch("troweprice_direct","PRFDX"); # Use this module only.
=head1 DESCRIPTION
This module obtains information about managed funds from T. Rowe Price.
Information about T. Rowe Price funds is available from a variety of
sources. The information source "troweprice" can be used if you don't
care which source you obtain information from. If you wish to be
guaranteed of fetching information from T. Rowe Price directly,
then the information source "troweprice_direct" should be used.
=head1 LABELS RETURNED
Information available from T. Rowe Price may include the following
labels: exchange, name, nav, date, price.
=head1 SEE ALSO
T. Rowe Price website - http://www.troweprice.com/
Finance::Quote::Yahoo::USA
=cut

View File

@@ -1,198 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
# Copyright (C) 2000, Keith Refson <Keith.Refson@earth.ox.ac.uk>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote::Trustnet;
require 5.004;
use strict;
use vars qw($VERSION $TRUSTNET_URL $TRUSTNET_ALL);
use LWP::UserAgent;
use HTTP::Request::Common;
use HTML::TableExtract;
$VERSION = '1.01';
# URLs of where to obtain information.
$TRUSTNET_URL = ("http://www.trustnet.co.uk/ut/funds/perf.asp?sort=0&txtS=");
$TRUSTNET_ALL="http://www.trustnet.co.uk/ut/funds/perf.asp?sort=0";
sub methods { return (uk_unit_trusts => \&trustnet, trustnet => \&trustnet); }
{
my @labels = qw/exchange method source name currency bid ask yield price/;
sub labels { return (trustnet => \@labels,
uk_unit_trusts => \@labels); }
}
# =======================================================================
sub trustnet
{
my $quoter = shift;
my @symbols = @_;
return unless @symbols;
my(@q,%aa,$ua,$url,$sym,$ts,$date,$price,$currency,$reply,$trust);
my ($row, $datarow, $matches);
my %curr_iso = ("<22>" => "GBP", "\$" => "USD");
my( $isodate, $day, $month, $year);
my %imonth = ( "Jan" => "01", "Feb" => "02", "Mar" => "03",
"Apr" => "04", "May" => "05", "Jun" => "06",
"Jul" => "07", "Aug" => "08", "Sep" => "09",
"Oct" => "10", "Nov" => "11", "Dec" => "12");
my %symbolhash;
@symbolhash{@symbols} = map(1,@symbols);
#
for (@symbols) {
my $te = new HTML::TableExtract( headers => [("Fund Name", "Group Name", "Bid Price", "Offer Price", "Yield")]);
$trust = $_;
$url = "$TRUSTNET_URL$trust";
# print STDERR "Retrieving \"$trust\" from $url\n";
$ua = $quoter->user_agent;
$reply = $ua->request(GET $url);
return unless ($reply->is_success);
# print STDERR $reply->content,"\n";
$te->parse($reply->content);
$ts = ($te->table_states)[0];
if( defined ($ts)) {
$matches = 0;
foreach $row ($ts->rows) {
($sym = $$row[0]) =~ s/^ +//;
if ($sym =~ /$trust/i) {
$matches++;
$datarow = $row;
}
}
if ($matches > 1 ) {
$aa {$trust, "success"} = 0;
$aa {$trust, "errormsg"} = "Fund name $trust is not unique. See \"$TRUSTNET_ALL\"";
next;
} elsif ($matches < 1 ) {
$aa {$trust, "success"} = 0;
#$aa {$trust, "errormsg"} = "Fund name $trust is not found. See \"$TRUSTNET_ALL\"";
$aa {$trust, "errormsg"} = "Error retrieving $trust -- unexpected input";
next;
} else {
$aa {$trust, "exchange"} = "Trustnet";
$aa {$trust, "method"} = "trustnet";
$aa {$trust, "source"} = "http://www.trustnet.co.uk/";
# ($aa {$trust, "name"} = $$datarow[0]) =~ s/^ +//;
$aa {$trust, "name"} = $trust; # no name supplied ...
($price = $$datarow[2]) =~ s/\s*\((.*)\)//;
$currency=$1;
$aa {$trust, "currency"} = $curr_iso{"$currency"};
$aa {$trust, "bid"} = $price * 0.01;
($price = $$datarow[3]) =~ s/\s*\((.*)\)//;
$price = $aa {$trust, "bid"} if $price eq "";
$aa {$trust, "ask"} = $price * 0.01;
$aa {$trust, "yield"} = $$datarow[4];
$aa {$trust, "price"} = $aa{$trust,"bid"};
$aa {$trust, "success"} = 1;
# print STDERR "Trustnet:: Flagging success for $trust\n";
#
# Get date and convert to US format (Ugh!)
$date= "notfound";
if ( $reply->content =~
/Source : TrustNet - ([\w\d-]+) - http:\/\/www.trustnet.com/m) {
$isodate=$1;
($day,$month,$year) = ($isodate =~ /([0-9]+)-(\w+)-([0-9]+)/);
$date = $imonth{$month}."/".$day."/".$year;
}
$aa {$trust, "date"} = $date;
}
} else {
$aa {$trust, "success"} = 0;
$aa {$trust, "errormsg"} = "Fund name $trust is not found. See \"$TRUSTNET_ALL\"";
next;
}
}
return %aa if wantarray;
return \%aa;
}
1;
=head1 NAME
Finance::Quote::Trustnet - Obtain unit trust prices from trustnet.co.uk
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%stockinfo = $q->fetch("unit_trusts","trust-name"); # Can failover to other methods
%stockinfo = $q->fetch("trustnex","trust-name"); # Use this module only.
=head1 DESCRIPTION
This module obtains information about UK unit trust prices from
www.trustnet.co.uk. The information source "unit_trusts" can be used
if the source of prices is irrelevant, and "trustnet" if you
specifically want to use trustnet.co.uk.
=head1 UNIT TRUST NAMES
Unfortunately there is no unique identifier for unit trust names.
Therefore enough of the name should be given including spaces to yield
a unique match. Trustnet sometimes uses abbreviated names, and the
string given should match the abbreviation.
Consult http://www.trustnet.co.uk/ut/funds/perf.asp?sort=0
to find a match for your unit trusts.
Example "jupiter income"
=head1 LABELS RETURNED
Information available from Trustnet may include the following labels:
exchange method source name currency bid ask yield price. In case of
a unit trust, "price" returns the offer (ask) price. In case of an
OIEC, the unique price is returned in "bid", "ask" and "price".
=head1 SEE ALSO
Trustnet website - http://www.trustnet.co.uk/
Finance::Quote::Yahoo::USA
=cut

View File

@@ -1,103 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
# This module defines our own LWP::UserAgent, in particular it allows
# user-defined headers to be set which will be automatically added to
# new HTTP requests. This is particularly important if you wish to get
# through authenticated proxies and the like.
package Finance::Quote::UserAgent;
require 5.005;
use strict;
use LWP::UserAgent;
use HTTP::Headers;
use vars qw/@ISA/;
@ISA = qw/LWP::UserAgent/;
# A very simple extension. When we generate a LWP::UserAgent object,
# we add an extra field called finance_quote_headers which stores an
# HTTP::Headers object.
sub new {
my $ua = LWP::UserAgent::new(@_);
$ua->{finance_quote_headers} = HTTP::Headers->new();
return $ua;
}
# This returns the HTTP::Headers object, so the user can play with it.
sub default_headers {
my $this = shift;
return $this->{finance_quote_headers};
}
# Over-ride for the simple_request method. This sets the user-supplied
# template headers if they have not already been set in the request.
sub simple_request {
my ($this, $request, @args) = @_;
my $new_request = $this->_add_custom_headers($request);
return $this->SUPER::simple_request($new_request,@args);
}
# Over-ride for the request method. This also sets the user-supplied
# template headers if they have not already been set in the request.
sub request {
my ($this, $request, @args) = @_;
my $new_request = $this->_add_custom_headers($request);
return $this->SUPER::request($new_request,@args);
}
# _add_custom_headers is a private method which does the dirty work
# of copying across headers and other fun things.
#
# We take the user-defined template, and then overlay the request over the
# top of it. This should get us by in most situations.
sub _add_custom_headers {
my ($this, $request) = @_;
my $header_template = $this->default_headers;
my $new_request = $request->clone; # Modifying the original is rude.
# Copy things that are in the template that we don't have
# defined in the request.
$header_template->scan(sub {
$new_request->header($_[0],$_[1]) unless
defined ($new_request->header($_[0]));
});
return $new_request;
}
# If users wish to place their username and proxy password(!) into
# the "http_proxy_auth_clear" environment variable, then we'll
# read it out and automatically use it for proxy requests.
sub env_proxy {
my ($this, @args) = @_;
if ($ENV{http_proxy_auth_clear}) {
$this->default_headers->proxy_authorization_basic(
split(/:/,$ENV{http_proxy_auth_clear}));
}
$this->SUPER::env_proxy(@_);
}
1;

View File

@@ -1,162 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@Acpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
# Copyright (C) 2000, Volker Stuerzl <volker.stuerzl@gmx.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
#
# $Id$
# =============================================================
# Workaround by Matt Sisk for handling newlines in table cells.
# Remove when fix of HTML::TableExtract is available.
package HTML::TableExtract::Workaround;
use HTML::TableExtract;
@ISA = qw( HTML::TableExtract );
sub start {
# Fool ourselves into translating <br> to "\n"
my $self = shift;
$self->text("\n") if $_[0] eq 'br';
$self->SUPER::start(@_);
}
# =============================================================
package Finance::Quote::VWD;
require 5.005;
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTML::TableExtract;
use vars qw/$VERSION $VWD_FUNDS_URL/;
$VERSION = '1.00';
$VWD_FUNDS_URL = "http://www.vwd.gfa-fonds.de/fondspreise/liste.hbs?suchtext=";
sub methods { return (vwd => \&vwd); }
sub labels { return (vwd => [qw/exchange name date price method/]); }
# =======================================================================
# The vwd routine gets quotes of funds from the website of
# vwd Vereinigte Wirtschaftsdienste GmbH.
#
# This subroutine was written by Volker Stuerzl <volker.stuerzl@gmx.de>
sub vwd
{
my $quoter = shift;
my @funds = @_;
return unless @funds;
my $ua = $quoter->user_agent;
my %info;
foreach my $fund (@funds)
{
my $response = $ua->request(GET $VWD_FUNDS_URL.$fund);
if ($response->is_success)
{
# parse table
my $te = new HTML::TableExtract::Workaround
(headers => [qw/WKN Name Whrg R<>ckn R<>ckn Zwg R<>ckn Ausgabe/]);
$te->parse($response->content);
# extract table contents
my @rows;
unless (@rows = $te->rows)
{
$info{$fund, "success"} = 0;
$info{$fund, "errormsg"} = "Parse error";
next;
}
# split fund and company name
my @name = split(/\n/, $rows[0][1]);
# grab date which is contained within table header
my $date;
$response->content =~ /R&uuml;ckn.<BR>&nbsp;(\d{2})\.(\d{2})\.(\d{4})/;
$date = $2."/".$1."/".$3;
# strip whitespace and non-printable characters from price and currency
$rows[0][2] =~ s/\W*//;
$rows[0][3] =~ s/[^\d.]*//g;
$info{$fund, "exchange"} = $name[1];
$info{$fund, "name"} = $name[0];
$info{$fund, "price"} = $rows[0][3];
$info{$fund, "last"} = $rows[0][3];
$info{$fund, "date"} = $date;
$info{$fund, "method"} = "vwd";
$info{$fund, "currency"} = $rows[0][2];
$info{$fund, "success"} = 1;
}
else
{
$info{$fund, "success"} = 0;
$info{$fund, "errormsg"} = "HTTP error";
}
}
return wantarray() ? %info : \%info;
}
1;
=head1 NAME
Finance::Quote::vwd - Obtain quotes from vwd Vereinigte Wirtschaftsdienste GmbH.
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%stockinfo = $q->fetch("vwd","847402");
=head1 DESCRIPTION
This module obtains information from vwd Vereinigte Wirtschaftsdienste GmbH
http://www.vwd.de/. Many european stocks and funds are available, but
at the moment only funds are supported.
Information returned by this module is governed by vwd's terms
and conditions.
=head1 LABELS RETURNED
The following labels may be returned by Finance::Quote::vwd:
exchange, name, date, price, last.
=head1 SEE ALSO
vwd Vereinigte Wirtschaftsdienste GmbH, http://www.vwd.de/
=cut

View File

@@ -1,123 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
package Finance::Quote::Yahoo::Australia;
require 5.005;
use strict;
use HTTP::Request::Common;
use LWP::UserAgent;
use Finance::Quote::Yahoo::Base qw/yahoo_request base_yahoo_labels/;
use vars qw/$VERSION $YAHOO_AUSTRALIA_URL/;
$VERSION = '1.00';
# URLs of where to obtain information.
$YAHOO_AUSTRALIA_URL = ("http://au.finance.yahoo.com/d/quotes.csv");
sub methods {return (australia => \&yahoo_australia,
yahoo_australia => \&yahoo_australia)};
{
my @labels = (base_yahoo_labels(),"currency","method","exchange");
sub labels { return (australia => \@labels,
yahoo_australia => \@labels); }
}
sub yahoo_australia
{
my $quoter = shift;
my @symbols = @_;
return unless @symbols; # Nothing if no symbols.
# Yahoo Australia needs AX. appended to indicate that we're
# dealing with Australian stocks.
# This does all the hard work.
my %info = yahoo_request($quoter,$YAHOO_AUSTRALIA_URL,\@symbols,".AX");
foreach my $symbol (@symbols) {
next unless $info{$symbol,"success"};
$info{$symbol,"currency"} = "AUD";
$info{$symbol,"exchange"} = "Australian Stock Exchange";
$info{$symbol,"method"} = "yahoo_australia";
}
return %info if wantarray;
return \%info;
}
1;
=head1 NAME
Finance::Quote::Yahoo::Australia - Fetch Australian stock quotes via Yahoo.
=head1 SYNOPSIS
use Finance::Quote;
my $q = Finance::Quote->new;
my %info = $q->fetch("yahoo_australia","BHP"); # Use this module only.
my %info = $q->fetch("australia","BHP"); # Failover with other methods.
=head1 DESCRIPTION
This module allows information to be fetched from Yahoo abouts stocks
traded on the Australian Stock Exchange. Information about indexes
(such as the All Ordinaries) are not available through this module,
although if information is requested from the "australia" source
then these will automatically failover to direct queries from the
Australian Stock Exchange.
This module is loaded by default on a Finance::Quote object, although
it can be explicitly loaded by passing the argument "Yahoo::Australia"
to Finance::Quote->new().
This module provides both the "australia" and "yahoo_australia" fetch
methods. You should use the "australia" method if you wish to allow
failovers to other sources, and "yahoo_australia" if you only want
to obtain quotes from this module.
Information obtained via this module is governed by Yahoo's terms
and conditions, see http://au.finance.yahoo.com/ for more details.
=head1 LABELS RETURNED
This module returns all the standard labels (where available)
provided by Yahoo, as well as the currency label. See
Finance::Quote::Yahoo::Base for more information.
=head1 SEE ALSO
Yahoo Australia, http://au.finance.yahoo.com/
Finance::Quote::Yahoo::Base
=cut

View File

@@ -1,207 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This package provides a base class for the various Yahoo services,
# and is based upon code by Xose Manoel Ramos <xmanoel@bigfoot.com>.
# Improvements based upon patches supplied by Peter Thatcher have
# also been integrated.
package Finance::Quote::Yahoo::Base;
require 5.005;
use strict;
use LWP::UserAgent;
use HTTP::Request::Common;
use Exporter;
use vars qw/$VERSION @FIELDS @FIELD_ENCODING $MAX_REQUEST_SIZE @ISA
@EXPORT @EXPORT_OK/;
@ISA = qw/Exporter/;
@EXPORT = qw//;
@EXPORT_OK = qw/yahoo_request base_yahoo_labels/;
$VERSION = '1.03';
# This is the maximum number of stocks we'll batch into one operation.
# If this gets too big (>50 or thereabouts) things will break because
# some proxies and/or webservers cannot handle very large URLS.
$MAX_REQUEST_SIZE = 40;
# Yahoo uses encodes the desired fields as 1-2 character strings
# in the URL. These are recorded below, along with their corresponding
# field names.
@FIELDS = qw/symbol name last date time net p_change volume bid ask
close open day_range year_range eps pe div_date div div_yield
cap ex_div avg_vol/;
@FIELD_ENCODING = qw/s n l1 d1 t1 c1 p2 v b a p o m w e r r1 d y j1 q a2/;
# This returns a list of labels that are provided, so that code
# that make use of this module can know what it's dealing with.
# It also means that if we extend the code in the future to provide
# more information, we simply need to change this in one spot.
sub base_yahoo_labels {
return (@FIELDS,"price","high","low");
}
# yahoo_request (restricted function)
#
# This function expects a Finance::Quote object, a base URL to use,
# a refernece to a list of symbols to lookup. If a fourth argument is
# used then it will act as a suffix that needs to be appended to the stocks
# in order to obtain the correct information. This function relies upon
# the fact that the various Yahoo's all work the same way.
sub yahoo_request {
my $quoter = shift;
my $base_url = shift;
# Extract our original symbols.
my @orig_symbols = @{shift()};
# The suffix is used to specify particular markets.
my $suffix = shift || "";
my %info;
my $ua = $quoter->user_agent;
# Generate a suitable URL, now all it needs is the
# ticker symbols.
$base_url .= "?f=".join("",@FIELD_ENCODING)."&e=.csv&s=";
while (my @symbols = splice(@orig_symbols,0,$MAX_REQUEST_SIZE)) {
# By pushing an extra symbol on to our array, we can
# be sure that everythng ends up with the correct suffix
# in the join() below.
push(@symbols,"");
my $url = $base_url . join("$suffix+",@symbols);
chop $url; # Chop off the final +
my $response = $ua->request(GET $url);
return unless $response->is_success;
# Okay, we have the data. Just stuff it in
# the hash now.
foreach (split('\015?\012',$response->content)) {
my @q = $quoter->parse_csv($_);
my $symbol = $q[0];
# Strip out suffixes. Mmmm, functions as lvalues.
substr($symbol,-length($suffix),length($suffix)) = "";
# If we weren't using a two dimesonal
# hash, we could do the following with
# a hash-slice. Alas, we can't. This just
# loads all the returned fields into our hash.
for (my $i=0; $i < @FIELDS; $i++) {
$info{$symbol,$FIELDS[$i]} = $q[$i];
}
# Yahoo returns a line filled with N/A's if we
# look up a non-existant symbol. AFAIK, the
# date flag will /never/ be defined properly
# unless we've looked up a real stock. Hence
# we can use this to check if we've
# successfully obtained the stock or not.
if ($info{$symbol,"date"} eq "N/A") {
$info{$symbol,"success"} = 0;
$info{$symbol,"errormsg"} = "Stock lookup failed";
next;
} else {
$info{$symbol,"success"} = 1;
}
$info{$symbol,"price"} = $info{$symbol,"last"};
# Remove spurious percentage signs in p_change.
$info{$symbol,"p_change"} =~ s/%//;
# Extract the high and low values from the
# day-range, if available
if ($info{$symbol,"day_range"} =~ m{^"?\s*(\S+)\s*-\s*(\S+)"?$}) {
$info{$symbol, "low"} = $1;
$info{$symbol, "high"} = $2;
}
} # End of processing each stock line.
} # End of lookup loop.
# Return undef's rather than N/As. This makes things more suitable
# for insertion into databases, etc. Also remove silly HTML that
# Yahoo inserts to put in little Euro symbols and stuff. It's
# pretty stupid to have HTML tags in a CSV file in the first
# place, don't you think?
foreach my $key (keys %info) {
$info{$key} =~ s/<[^>]*>//g;
$info{$key} =~ s/&nbsp;.*$//;
undef $info{$key} if (defined($info{$key}) and
$info{$key} eq "N/A");
}
return %info if wantarray;
return \%info;
}
1;
=head1 NAME
Finance::Quote::Yahoo::Base - Common functions for fetching Yahoo info.
=head1 SYNOPSIS
Base functions for use by the Finance::Quote::Yahoo::* modules.
=head1 DESCRIPTION
This module is not called directly, rather it provides a set of
base functions which other Yahoo-related modules can use. If you're
thinking of writing a module to fetch specific information from
Yahoo, then you might wish to look through the source code for
this module.
=head1 LABELS RETURNED
Most Yahoo functions will return a standard set of labels. These
include (where available): symbol, name, last, date, time, net,
p_change, volume, bid, ask close, open, day_range, year_range, eps,
pe, div_date, div, div_yield, cap, ex_div, avg_vol.
=head1 SEE ALSO
Finance::Quote::Yahoo::Australia, Finance::Quote::Yahoo::USA,
Finance::Quote::Yahoo::Europe.
=cut

View File

@@ -1,154 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote::Yahoo::Europe;
require 5.005;
use strict;
use HTTP::Request::Common;
use LWP::UserAgent;
use Finance::Quote::Yahoo::Base qw/yahoo_request base_yahoo_labels/;
use vars qw($VERSION $YAHOO_EUROPE_URL);
$VERSION = '1.02';
# URLs of where to obtain information.
$YAHOO_EUROPE_URL = ("http://finance.uk.yahoo.com/d/quotes.csv");
sub methods {return (europe => \&yahoo_europe,yahoo_europe => \&yahoo_europe)};
{
my @labels = (base_yahoo_labels(),"currency","method");
sub labels { return (europe => \@labels, yahoo_europe => \@labels); }
}
# =======================================================================
# yahoo_europe gets quotes for European markets from Yahoo.
sub yahoo_europe
{
my $quoter = shift;
my @symbols = @_;
return unless @symbols; # Nothing if no symbols.
# This does all the hard work.
my %info = yahoo_request($quoter,$YAHOO_EUROPE_URL,\@symbols);
foreach my $symbol (@symbols) {
if ($info{$symbol,"success"}) {
$info{$symbol,"method"} = "yahoo_europe";
# London sources return in pence, not Euros.
# We'd like them to return in pounds (divide
# by 100).
if ($symbol =~ /\.L$/i) {
$info{$symbol,"currency"} = "GBP";
foreach my $field ($quoter->default_currency_fields) {
next unless ($info{$symbol,$field});
$info{$symbol,$field} = $quoter->scale_field($info{$symbol,$field},0.01);
}
} elsif (substr($symbol,0,1) ne "^") {
# All other non-indexes are in Euros.
$info{$symbol,"currency"} = "EUR";
} else {
$info{$symbol,"currency"} = undef;
}
}
}
return %info if wantarray;
return \%info;
}
1;
=head1 NAME
Finance::Quote::Yahoo::Europe - Fetch quotes from Yahoo Europe
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%info = $q->fetch("europe","12150.PA"); # Failover to other methods ok.
%info = $q->fetch("yahoo_europe","12150.PA"); # Use this module only.
=head1 DESCRIPTION
This module fetches information from Yahoo Europe. Symbols should be
provided in the format "SYMBOL.EXCHANGE", where the exchange code is
one of the following:
PA - Paris
BC - Barcelona
BE - Berlin
BI - Bilbao
BR - Breme
CO - Copenhagen
D - Dusseldorf
F - Frankfurt
H - Hamburg
HA - Hanover
L - London
MA - Madrid
MC - Madrid (M.C.)
MI - Milan
MU - Munich
O - Oslo
ST - Stockholm
SG - Stuttgart
VA - Valence
DE - Xetra (was FX)
This module provides both the "europe" and "yahoo_europe" methods.
The "europe" method should be used if failover methods are desirable.
The "yahoo_europe" method should be used you desire to only fetch
information from Yahoo Europe.
This module is loaded by default by Finance::Quote, but can be loaded
explicitly by specifying the parameter "Yahoo::Europe" to
Finance::Quote->new().
Information obtained by this module may be covered by Yahoo's terms
and conditions. See http://finance.uk.yahoo.com/ for more details.
=head1 LABELS RETURNED
This module returns all the standard labels (where available) provided
by Yahoo. See Finance::Quote::Yahoo::Base for a list of these. The
currency label is also returned.
=head1 SEE ALSO
Yahoo Europe, http://finance.uk.yahoo.com/
=cut

View File

@@ -1,189 +0,0 @@
#!/usr/bin/perl -w
#
# Copyright (C) 1998, Dj Padzensky <djpadz@padz.net>
# Copyright (C) 1998, 1999 Linas Vepstas <linas@linas.org>
# Copyright (C) 2000, Yannick LE NY <y-le-ny@ifrance.com>
# Copyright (C) 2000, Paul Fenwick <pjf@cpan.org>
# Copyright (C) 2000, Brent Neal <brentn@users.sourceforge.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
#
# This code derived from Padzensky's work on package Finance::YahooQuote,
# but extends its capabilites to encompas a greater number of data sources.
#
# This code was developed as part of GnuCash <http://www.gnucash.org/>
package Finance::Quote::Yahoo::USA;
require 5.005;
use strict;
use HTTP::Request::Common;
use LWP::UserAgent;
use Finance::Quote::Yahoo::Base qw/yahoo_request base_yahoo_labels/;
use vars qw/$VERSION $YAHOO_URL/;
$VERSION = '1.00';
# URLs of where to obtain information.
$YAHOO_URL = ("http://finance.yahoo.com/d");
sub methods {return (canada => \&yahoo,
usa => \&yahoo,
yahoo => \&yahoo,
nyse => \&yahoo,
nasdaq => \&yahoo,
vanguard => \&yahoo,
fidelity => \&yahoo_fidelity)};
{
my @labels = (base_yahoo_labels(),"currency", "method");
sub labels { return (canada => \@labels,
usa => \@labels,
yahoo => \@labels,
nyse => \@labels,
nasdaq => \@labels,
vanguard => \@labels,
fidelity => [@labels,'yield','nav']); }
}
# This is a special wrapper to provide information compatible with
# the primary Fidelity function of Finance::Quote. It does a good
# job of a failover.
{
# Really this list should be common for both the Fidelity.pm
# and this module. We could possibly get away with checking
# for /XX$/, but I don't know how reliable that is.
my %yield_funds = (FDRXX => 1,
FDTXX => 1,
FGMXX => 1,
FRTXX => 1,
SPRXX => 1,
SPAXX => 1,
FDLXX => 1,
FGRXX => 1);
sub yahoo_fidelity {
my $quoter = shift;
my @symbols = @_;
return unless @symbols;
# Call the normal yahoo function (defined later in this
# file).
my %info = yahoo($quoter,@symbols);
foreach my $symbol (@symbols) {
next unless $info{$symbol,"success"};
if ($yield_funds{$symbol}) {
$info{$symbol,"yield"}=$info{$symbol,"price"};
} else {
$info{$symbol,"nav"} = $info{$symbol,"price"};
}
}
return wantarray ? %info : \%info;
}
}
sub yahoo
{
my $quoter = shift;
my @symbols = @_;
return unless @symbols; # Nothing if no symbols.
# This does all the hard work.
my %info = yahoo_request($quoter,$YAHOO_URL,\@symbols);
foreach my $symbol (@symbols) {
# Yahoo indexes all start with a hat, so don't
# tag them with a currency.
if ($info{$symbol,"success"} and $symbol !~ /^\^/) {
$info{$symbol,"currency"} = "USD";
$info{$symbol,"method"} = "yahoo";
}
}
return %info if wantarray;
return \%info;
}
1;
=head1 NAME
Finance::Quote::Yahoo::USA - Obtain information about stocks and funds
in the USA and Canada.
=head1 SYNOPSIS
use Finance::Quote;
$q = Finance::Quote->new;
%info = $q->fetch("usa","SGI");
=head1 DESCRIPTION
This method provides access to financial information from a number
of exhcanges in the United States and Canada. The following methods
are available:
canada
usa
yahoo
nyse
nasdaq
vanguard
fidelity
These methods all use the same information source, and hence can
be considered somewhat interchangable. However, the method "yahoo"
should be passed to fetch if you wish to obtain information
from any source that Yahoo tracks.
This method is loaded by default by Finance::Quote, although it
can be explicitly loaded by passing the argument "Yahoo::USA"
to Finance::Quote->new().
Information returned by this module may be subject to Yahoo's
terms and conditions. See http://finance.yahoo.com/ for more
information.
=head1 LABELS RETURNED
This module returns all the standard labels that Yahoo provides,
as well as the currency label. See Finance::Quote::Yahoo::Base
for more information.
=head1 BUGS
Yahoo does not make a distinction between the various exchanges
in the United States and Canada. For example, it is possible to request
a stock using the "NYSE" method and still obtain data even if that stock
does not exist on the NYSE but exists on a different exchange.
=head1 SEE ALSO
Yahoo Finance, http://finance.yahoo.com/
Finance::Quote::Base
=cut

View File

@@ -1,16 +0,0 @@
#!/usr/bin/perl -w
# Test to see if Finance::Quote can at least be loaded and used.
# This file gets a capital name so it will be run before any other
# test.
use strict;
use Test;
BEGIN {plan tests => 2};
use Finance::Quote;
ok(1); # Yup. It loaded okay. Good. :)
my $quote = Finance::Quote->new();
ok($quote); # Did we get an object okay?

View File

@@ -1,40 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 11};
use Finance::Quote;
# Test ASX functions.
my $q = Finance::Quote->new();
$q->timeout(120); # ASX is broken regularly, so timeouts are good.
my %quotes = $q->asx("CML","BHP");
ok(%quotes);
# Check the last values are defined. These are the most used and most
# reliable indicators of success.
ok($quotes{"CML","last"} > 0);
ok($quotes{"CML","success"});
ok($quotes{"BHP","last"} > 0);
ok($quotes{"BHP","success"});
# Exercise the fetch function a little.
%quotes = $q->fetch("asx","ITE");
ok(%quotes);
ok($quotes{"ITE","last"} > 0);
ok($quotes{"ITE","success"} > 0);
# Check that we're getting currency information.
ok($quotes{"ITE", "currency"} eq "AUD");
# Check we're not getting bogus percentage signs.
$quotes{"ITE","p_change"} ||= ""; # Avoid warning if undefined.
ok($quotes{"ITE","p_change"} !~ /%/);
# Check that looking up a bogus stock returns failure:
%quotes = $q->asx("BOG");
ok(! $quotes{"BOG","success"});

View File

@@ -1,31 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 8};
use Finance::Quote;
# Test currency conversion, both explicit requests and automatic
# conversion.
my $q = Finance::Quote->new();
# Explicit conversion...
ok($q->currency("USD","AUD"));
ok($q->currency("EUR","JPY"));
ok(! defined($q->currency("XXX","YYY")));
ok(($q->currency("10 AUD","AUD")) == (10 * ($q->currency("AUD","AUD"))));
# Euros into French Francs are fixed at a conversion rate of
# 1:6.559576 . We can use this knowledge to test that a stock is
# converting correctly.
my %baseinfo = $q->fetch("europe","12150.PA");
ok($baseinfo{"12150.PA","success"});
$q->set_currency("FRF"); # All new requests in French Francs.
my %info = $q->fetch("europe","12150.PA");
ok($info{"12150.PA","success"});
ok($info{"12150.PA","currency"} eq "FRF");
ok($info{"12150.PA","price"} > 0);

View File

@@ -1,22 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 6};
use Finance::Quote;
# Test DWS functions.
my $q = Finance::Quote->new("DWS");
my %quotes = $q->fetch("dwsfunds","847402","BOGUS");
ok(%quotes);
# Check that the last and date values are defined.
ok($quotes{"847402","success"});
ok($quotes{"847402","last"} > 0);
ok(length($quotes{"847402","date"}) > 0);
ok($quotes{"847402","currency"} eq "EUR");
# Check that a bogus fund returns no-success.
ok(! $quotes{"BOGUS","success"});

View File

@@ -1,34 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 23};
use Finance::Quote;
# Test Fidelity functions.
my $q = Finance::Quote->new();
my @funds = qw/FGRIX FNMIX FASGX FCONX/;
my %quotes = $q->fidelity(@funds);
ok(%quotes);
# Check that the name and nav are defined for all of the funds.
foreach my $fund (@funds) {
ok($quotes{$fund,"nav"} > 0);
ok(length($quotes{$fund,"name"}));
ok($quotes{$fund,"success"});
ok($quotes{$fund, "currency"} eq "USD");
}
# Some funds have yields instead of navs. Check one of them too.
%quotes = $q->fidelity("FGRXX");
ok(%quotes);
ok(length($quotes{"FGRXX","name"}));
ok($quotes{"FGRXX","yield"} != 0);
ok($quotes{"FGRXX","success"});
ok($quotes{"FGRXX", "currency"} eq "USD");
# Check that a bogus fund returns no-success.
%quotes = $q->fidelity("BOGUS");
ok(! $quotes{"BOGUS","success"});

View File

@@ -1,24 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 8};
use Finance::Quote;
# Test TIAA-CREF functions.
my $q = Finance::Quote->new();
my %quotes = $q->tiaacref("CREFmony","TIAAreal","BOGOname");
ok(%quotes);
ok($quotes{"CREFmony","nav"} > 0);
ok($quotes{"CREFmony", "currency"} eq "USD");
ok(length($quotes{"CREFmony","date"}) > 0);
ok($quotes{"TIAAreal","nav"} > 0);
ok(length($quotes{"TIAAreal","date"}) > 0);
ok($quotes{"BOGOname","success"} == 0);
ok($quotes{"BOGOname","errormsg"} eq "Bad symbol");

View File

@@ -1,29 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 9};
use Finance::Quote;
# Test troweprice functions.
my $q = Finance::Quote->new();
my %quotes = $q->troweprice;
ok(%quotes);
# Check that nav and date are defined as our tests.
ok($quotes{"PRFDX","nav"} > 0);
ok($quotes{"PRFDX","success"});
ok($quotes{"PRFDX","currency"} eq "USD");
ok(length($quotes{"PRFDX","date"}) > 0);
ok($quotes{"PRIDX","success"});
ok($quotes{"PRIDX","nav"} > 0);
ok(length($quotes{"PRIDX","date"}) > 0);
# Check a bogus fund returns no-success
%quotes = $q->troweprice("BOGUS");
ok(! $quotes{"BOGUS","success"});

View File

@@ -1,31 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 8 };
use Finance::Quote;
# Test trustnet functions.
my $q = Finance::Quote->new();
my @stocks = ("ABBEY AMERICAN GROWTH","PERPETUAL GLOBAL BOND");
my %quotes = $q->fetch("trustnet",@stocks);
ok(%quotes);
# For each of our stocks, check to make sure we got back some
# useful information.
foreach my $stock (@stocks) {
ok($quotes{$stock,"success"});
ok($quotes{$stock,"price"});
ok($quotes{$stock,"date"});
}
# Test that a bogus stock gets no success.
%quotes = $q->fetch("trustnet","BOGUS");
ok(! $quotes{"BOGUS","success"});

View File

@@ -1,26 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 18};
use Finance::Quote;
# Test Vanguard functions.
my $q = Finance::Quote->new();
my @funds = qw/VBINX VIVAX VWINX VFIIX/;
my %quotes = $q->vanguard(@funds);
ok(%quotes);
# Check that the name and last are defined for all of the funds.
foreach my $fund (@funds) {
ok($quotes{$fund,"last"} > 0);
ok(length($quotes{$fund,"name"}));
ok($quotes{$fund,"success"});
ok($quotes{$fund, "currency"} eq "USD");
}
# Make sure we're not getting spurious percentage signs.
ok($quotes{"VBINX","p_change"} !~ /%/);

View File

@@ -1,23 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 7};
use Finance::Quote;
# Test vwd functions.
my $q = Finance::Quote->new("VWD");
my %quotes = $q->vwd("847402","BOGUS");
ok(%quotes);
# Check that the last and date values are defined.
ok($quotes{"847402","success"});
ok($quotes{"847402","last"} > 0);
ok(length($quotes{"847402","date"}) > 0);
ok($quotes{"847402","currency"} eq "EUR");
# Check that a bogus fund returns no-success.
ok($quotes{"BOGUS","success"} == 0);
ok($quotes{"BOGUS","errormsg"} eq "Parse error");

View File

@@ -1,30 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
BEGIN {plan tests => 8};
use Finance::Quote;
# Test Yahoo functions.
my $q = Finance::Quote->new();
my %quotes = $q->yahoo("IBM","SGI","BOGUS");
ok(%quotes);
# Check the last values are defined. These are the most
# used and most reliable indicators of success.
ok($quotes{"IBM","last"} > 0);
ok($quotes{"IBM","success"});
ok($quotes{"IBM", "currency"} eq "USD");
ok($quotes{"SGI","last"} > 0);
ok($quotes{"SGI","success"});
# Make sure there are no spurious % signs.
ok($quotes{"SGI","p_change"} !~ /%/);
# Check that bogus stocks return failure:
ok(! $quotes{"BOGUS","success"});

View File

@@ -1,34 +0,0 @@
#!/usr/bin/perl -w
use strict;
use Test;
use Data::Dumper;
BEGIN {plan tests => 9};
use Finance::Quote;
# Test Yahoo_europe functions.
my $q = Finance::Quote->new();
my %quotes = $q->yahoo_europe("12150.PA","BOGUS");
ok(%quotes);
# Check the nav values are defined. These are the most
# used and most reliable indicators of success.
ok($quotes{"12150.PA","last"} > 0);
ok(length($quotes{"12150.PA","name"}) > 0);
ok($quotes{"12150.PA","success"});
ok($quotes{"12150.PA", "currency"} eq "EUR");
# Make sure we don't have spurious % signs.
ok($quotes{"12150.PA","p_change"} !~ /%/);
# Check that a bogus stock returns no-success.
ok(! $quotes{"BOGUS","success"});
# London stocks should be returned in British Pounds (GBP).
my %londonquotes = $q->fetch("yahoo_europe","BAY.L");
ok($londonquotes{"BAY.L","success"});
ok($londonquotes{"BAY.L","currency"} eq "GBP");

View File

@@ -6,18 +6,4 @@ order to build gnucash, but isn't considered widely available.
Finance::Quote
--------------
Building and installing Finance::Quote is fairly simple. It is needed
to perform stock lookups with gnc-prices and other programs. It can
be built after GnuCash if required. (If you try to use gnc-prices and
other scripts without Finance::Quote installed, you'll get an ugly
error message.)
Building is simple. In the Finance-Quote-1.05 directory:
perl Makefile.PL
make
make test (optional)
make install (as root)
This will install the module into the appropriate place where perl modules
live on your system.
Available from http://finance-quote.sourceforge.net.