mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
@@ -1,3 +0,0 @@
|
||||
Makefile
|
||||
blib
|
||||
pm_to_blib
|
||||
@@ -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
|
||||
|
||||
@@ -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>.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -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/
|
||||
@@ -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";
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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";
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
@@ -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"
|
||||
);
|
||||
@@ -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
|
||||
@@ -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/ //; # 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/ //;
|
||||
|
||||
$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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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ückn.<BR> (\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
|
||||
@@ -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
|
||||
@@ -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/ .*$//;
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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?
|
||||
@@ -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"});
|
||||
|
||||
@@ -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);
|
||||
@@ -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"});
|
||||
@@ -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"});
|
||||
@@ -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");
|
||||
|
||||
@@ -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"});
|
||||
@@ -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"});
|
||||
@@ -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"} !~ /%/);
|
||||
@@ -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");
|
||||
@@ -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"});
|
||||
@@ -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");
|
||||
16
lib/README
16
lib/README
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user