Skip Menu |

This queue is for tickets about the Finance-Quote CPAN distribution.

Report information
The Basics
Id: 40731
Status: open
Priority: 0/
Queue: Finance-Quote

People
Owner: eco [...] ecocode.net
Requestors: fredrik.p.persson [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: New script
Hello! I've written a "plugin" that fetches quotes for funds from www.morningstar.se. However, it does not work with gnucash. (I'm using Ubuntu 8.10 with gnucash 2.2.6 and Finance::Quote 1.13 since those are the versions in Ubuntu 8.10). Script attached. Does anyone know why it won't give gnucash what gnucash wants?
Subject: Ftest.pm
package Finance::Quote::Ftest; require 5.004; use strict; use vars qw($VERSION $MORNINGSTAR_SE_FUNDS_URL); use LWP::UserAgent; use HTTP::Request::Common; use HTML::TableExtract; $VERSION = '1.0'; $MORNINGSTAR_SE_FUNDS_URL = 'http://morningstar.se/funds/overview.asp?cid='; sub methods { return (ftest_funds => \&ftest_funds); } { my @labels = qw/date isodate method source name currency price/; sub labels { return (fredrik_funds => \@labels); } } sub ftest_funds { my $quoter = shift; my @symbols = @_; return unless @symbols; my ($ua, $reply, $url, %funds, $te, $table, $row, @value_currency, $name); print "I am in my module!\n"; #$name = "FOGBR05U5Z"; $name = $symbols[0]; $url = $MORNINGSTAR_SE_FUNDS_URL; $url = $url . $name; $ua = $quoter->user_agent; $reply = $ua->request(GET $url); unless ($reply->is_success) { foreach my $symbol (@symbols) { $funds{$symbol, "success"} = 0; $funds{$symbol, "errormsg"} = "HTTP failure"; } return wantarray ? %funds : \%funds; } $te = new HTML::TableExtract(); $te->parse($reply->content); #print "Tables: " . $te->tables_report() . "\n"; my $counter = 0; my $dateset = 0; for my $table ($te->tables()) { for my $row ($table->rows()) { #print $$row[1] . "\n"; if ('Senaste NAV' eq substr($$row[0],0,11)) { @value_currency = split(/ /, $$row[2]); $funds{$name, 'method'} = 'fredrik_funds'; $funds{$name, 'price'} = $value_currency[0]; $funds{$name, 'currency'} = $value_currency[1]; $funds{$name, 'success'} = 1; $funds{$name, 'symbol'} = $name; $funds{$name, 'source'} = 'Finance::Quote::Ftest'; $funds{$name, 'name'} = $name; } if ($counter == 7 && $dateset == 0) { my $date = substr($$row[1],0,10); print "Date gotten: ", $date, "\n"; $quoter->store_date(\%funds, $name, {isodate => $date}); $dateset = 1; } } $counter++; } # Check for undefined symbols foreach my $symbol (@symbols) { unless ($funds{$symbol, 'success'}) { $funds{$symbol, "success"} = 0; $funds{$symbol, "errormsg"} = "Fund name not found"; } } return %funds if wantarray; return \%funds; } 1; =head1 NAME Finance::Quote::Ftest - Obtain fund prices the Fredrik way =head1 SYNOPSIS use Finance::Quote; $q = Finance::Quote->new; %fundinfo = $q->fetch("fredrik_funds","fund name"); =head1 DESCRIPTION This module obtains information about Fredrik fund prices from www.morningstar.se. =head1 FUND NAMES Use some smart fund name... =head1 LABELS RETURNED Information available from Fredrik funds may include the following labels: date method source name currency price. The prices are updated at the end of each bank day. =head1 SEE ALSO Perhaps morningstar? =cut
From: fredrik.p.persson [...] gmail.com
I forgot to add a few symbols for testing; here are a few: FXIRL00109 F0000001OD NTFEB00442 FXLUX03658
From: dbreiser [...] gmail.com
On Thu Nov 06 16:19:58 2008, garton wrote: Show quoted text
> Hello! > > I've written a "plugin" that fetches quotes for funds from > www.morningstar.se. However, it does not work with gnucash. (I'm using > Ubuntu 8.10 with gnucash 2.2.6 and Finance::Quote 1.13 since those are > the versions in Ubuntu 8.10). > > Script attached. Does anyone know why it won't give gnucash what gnucash > wants?
Yes. Get rid of the print statements. Also, when I do: echo '(ftest_funds "FXIRL00109")' | gnc-fq-helper I get 36 complaints of: Use of uninitialized value in substr at /sw/lib/perl5/5.8.8/Finance/Quote/Ftest.pm line 54, <> line 1. While these errors don't appear to get in the way of gnucash getting the quote, it would probably be better to initialize whatever variable it is complaining about.
From: fredrik.p.persson [...] gmail.com
On Sat Nov 08 01:43:11 2008, dbreiser wrote: Show quoted text
> Yes. Get rid of the print statements. > > Also, when I do: > echo '(ftest_funds "FXIRL00109")' | gnc-fq-helper > I get 36 complaints of: > Use of uninitialized value in substr at > /sw/lib/perl5/5.8.8/Finance/Quote/Ftest.pm line 54, <> line 1. > > While these errors don't appear to get in the way of gnucash getting the > quote, it would probably be better to initialize whatever variable it is > complaining about.
Ok, I've fixed that now. Attaching new version. This time, gnucash manages to handle the quote *for some quotes, but not others*! The symbol "FXXIN06789" works fine. The symbols "NTJUL00779" and "FXIRL00109" gets the same error as before. But I see no difference between those results in gnc-fq-helper.
package Finance::Quote::Ftest; require 5.004; use strict; use vars qw($VERSION $MORNINGSTAR_SE_FUNDS_URL); use LWP::UserAgent; use HTTP::Request::Common; use HTML::TableExtract; $VERSION = '1.0'; $MORNINGSTAR_SE_FUNDS_URL = 'http://morningstar.se/funds/overview.asp?cid='; sub methods { return (ftest_funds => \&ftest_funds); } { my @labels = qw/date isodate method source name currency price/; sub labels { return (fredrik_funds => \@labels); } } sub ftest_funds { my $quoter = shift; my @symbols = @_; return unless @symbols; my ($ua, $reply, $url, %funds, $te, $table, $row, @value_currency, $name); $name = $symbols[0]; $url = $MORNINGSTAR_SE_FUNDS_URL; $url = $url . $name; $ua = $quoter->user_agent; $reply = $ua->request(GET $url); unless ($reply->is_success) { foreach my $symbol (@symbols) { $funds{$symbol, "success"} = 0; $funds{$symbol, "errormsg"} = "HTTP failure"; } return wantarray ? %funds : \%funds; } $te = new HTML::TableExtract(); $te->parse($reply->content); #print "Tables: " . $te->tables_report() . "\n"; my $counter = 0; my $dateset = 0; for my $table ($te->tables()) { for my $row ($table->rows()) { if (defined(@$row[0])) { if ('Senaste NAV' eq substr(@$row[0],0,11)) { @value_currency = split(/ /, $$row[2]); $funds{$name, 'method'} = 'fredrik_funds'; $funds{$name, 'price'} = $value_currency[0]; $funds{$name, 'currency'} = $value_currency[1]; $funds{$name, 'success'} = 1; $funds{$name, 'symbol'} = $name; $funds{$name, 'source'} = 'Finance::Quote::Ftest'; $funds{$name, 'name'} = $name; } if ($counter == 7 && $dateset == 0) { my $date = substr($$row[1],0,10); $quoter->store_date(\%funds, $name, {isodate => $date}); $dateset = 1; } } } $counter++; } # Check for undefined symbols foreach my $symbol (@symbols) { unless ($funds{$symbol, 'success'}) { $funds{$symbol, "success"} = 0; $funds{$symbol, "errormsg"} = "Fund name not found"; } } return %funds if wantarray; return \%funds; } 1; =head1 NAME Finance::Quote::Ftest - Obtain fund prices the Fredrik way =head1 SYNOPSIS use Finance::Quote; $q = Finance::Quote->new; %fundinfo = $q->fetch("fredrik_funds","fund name"); =head1 DESCRIPTION This module obtains information about Fredrik fund prices from www.morningstar.se. =head1 FUND NAMES Use some smart fund name... =head1 LABELS RETURNED Information available from Fredrik funds may include the following labels: date method source name currency price. The prices are updated at the end of each bank day. =head1 SEE ALSO Perhaps morningstar? =cut
From: fredrik.p.persson [...] gmail.com
I found out what was wrong with this; it didn't handle multiple quotes but only the first quote requested was ever returned. This is now fixed. You're very welcome to add this to the official Fincance::Quote package. Perhaps it needs a copyright text and a more approprate name though?
package Finance::Quote::Ftest; require 5.004; use strict; use vars qw($VERSION $MORNINGSTAR_SE_FUNDS_URL); use LWP::UserAgent; use HTTP::Request::Common; use HTML::TableExtract; $VERSION = '1.0'; $MORNINGSTAR_SE_FUNDS_URL = 'http://morningstar.se/funds/overview.asp?cid='; sub methods { return (ftest_funds => \&ftest_funds); } { my @labels = qw/date isodate method source name currency price/; sub labels { return (fredrik_funds => \@labels); } } sub ftest_funds { my $quoter = shift; my @symbols = @_; return unless @symbols; my ($ua, $reply, $url, %funds, $te, $table, $row, @value_currency, $name); foreach my $symbol (@symbols) { $name = $symbol; $url = $MORNINGSTAR_SE_FUNDS_URL; $url = $url . $name; $ua = $quoter->user_agent; $reply = $ua->request(GET $url); unless ($reply->is_success) { foreach my $symbol (@symbols) { $funds{$symbol, "success"} = 0; $funds{$symbol, "errormsg"} = "HTTP failure"; } return wantarray ? %funds : \%funds; } $te = new HTML::TableExtract(); $te->parse($reply->content); #print "Tables: " . $te->tables_report() . "\n"; my $counter = 0; my $dateset = 0; for my $table ($te->tables()) { for my $row ($table->rows()) { if (defined(@$row[0])) { if ('Senaste NAV' eq substr(@$row[0],0,11)) { @value_currency = split(/ /, $$row[2]); $funds{$name, 'method'} = 'fredrik_funds'; $funds{$name, 'price'} = $value_currency[0]; $funds{$name, 'currency'} = $value_currency[1]; $funds{$name, 'success'} = 1; $funds{$name, 'symbol'} = $name; $funds{$name, 'source'} = 'Finance::Quote::Ftest'; $funds{$name, 'name'} = $name; } if ($counter == 7 && $dateset == 0) { my $date = substr($$row[1],0,10); $quoter->store_date(\%funds, $name, {isodate => $date}); $dateset = 1; } } } $counter++; } # Check for undefined symbols foreach my $symbol (@symbols) { unless ($funds{$symbol, 'success'}) { $funds{$symbol, "success"} = 0; $funds{$symbol, "errormsg"} = "Fund name not found"; } } } return %funds if wantarray; return \%funds; } 1; =head1 NAME Finance::Quote::Ftest - Obtain fund prices the Fredrik way =head1 SYNOPSIS use Finance::Quote; $q = Finance::Quote->new; %fundinfo = $q->fetch("fredrik_funds","fund name"); =head1 DESCRIPTION This module obtains information about Fredrik fund prices from www.morningstar.se. =head1 FUND NAMES Use some smart fund name... =head1 LABELS RETURNED Information available from Fredrik funds may include the following labels: date method source name currency price. The prices are updated at the end of each bank day. =head1 SEE ALSO Perhaps morningstar? =cut
Garton, Thanks for your work! I would need a test file for adding the new module to the package. Can you provide one ? -- Erik
From: fredrik.p.persson [...] gmail.com
On Fri Dec 05 13:20:17 2008, ecocode wrote: Show quoted text
> Garton, > > Thanks for your work! > I would need a test file for adding the new module to the package. Can > you provide one ?
I'd love to. But I'm not sure that I know what that is. I'm attaching a html file from www.morningstar.se that this module can parse. Use it with the symbol given in the file name. Is this what you wanted?

Message body is not shown because it is too large.

Subject: Re: [rt.cpan.org #40731] New script
Date: Fri, 5 Dec 2008 21:47:07 +0100
To: bug-Finance-Quote [...] rt.cpan.org
From: Erik Colson <eco [...] ecocode.net>
On 05 Dec 2008, at 21:37, Fredrik Persson via RT wrote: Show quoted text
>> I would need a test file for adding the new module to the package. >> Can >> you provide one ?
> > > I'd love to. But I'm not sure that I know what that is. I'm > attaching a > html file from www.morningstar.se that this module can parse. Use it > with the symbol given in the file name. Is this what you wanted?
Hello Fredrik, It's not really what I need... Take a look at the code hereafter (yahoo_europe.t). It is a perl script. It checks if existing quotes are returned, dates are really dates etc... -- Erik =============================================================== #!/usr/bin/perl -w use strict; use Test::More; use Finance::Quote; if (not $ENV{ONLINE_TEST}) { plan skip_all => 'Set $ENV{ONLINE_TEST} to run this test'; } plan tests => 21; # Test Yahoo_europe functions. my $q = Finance::Quote->new(); my $year = (localtime())[5] + 1900; my $lastyear = $year - 1; my %quotes = $q->yahoo_europe("UG.PA","BOGUS.L"); ok(%quotes); # Check the nav values are defined. These are the most # used and most reliable indicators of success. ok($quotes{"UG.PA","last"} > 0); ok(length($quotes{"UG.PA","name"}) > 0); ok($quotes{"UG.PA","success"}); ok($quotes{"UG.PA", "currency"} eq "EUR"); ok(substr($quotes{"UG.PA","isodate"},0,4) == $year || substr($quotes{"UG.PA","isodate"},0,4) == $lastyear); ok(substr($quotes{"UG.PA","date"},6,4) == $year || substr($quotes{"UG.PA","date"},6,4) == $lastyear); # Make sure we don't have spurious % signs. ok($quotes{"UG.PA","p_change"} !~ /%/); # Check that a bogus stock returns no-success. ok(! $quotes{"BOGUS","success"}); # London stocks can be returned in a variety of currencies my %londonquotes = $q->fetch("yahoo_europe","BAY.L"); ok($londonquotes{"BAY.L","success"}); ok($londonquotes{"BAY.L","currency"} eq "GBP"); ok(($londonquotes{"BAY.L","currency"} eq "GBP") && !defined($londonquotes{"BAY.L","currency_set_by_fq"})); %londonquotes = $q->fetch("yahoo_europe","CCR.L"); ok($londonquotes{"CCR.L","success"}); ok($londonquotes{"CCR.L","currency"} eq "EUR"); ok(($londonquotes{"CCR.L","currency"} eq "EUR") && !defined($londonquotes{"CCR.L","currency_set_by_fq"})); # Copenhangen stocks should be returned in Danisk Krone (DKK). my %copenhagenquotes = $q->fetch("yahoo_europe","TDC.CO"); ok($copenhagenquotes{"TDC.CO","success"}); ok($copenhagenquotes{"TDC.CO","currency"} eq "DKK"); ok(($copenhagenquotes{"TDC.CO","currency"} eq "DKK") && !defined($copenhagenquotes{"TDC.CO","currency_set_by_fq"})); # Two stocks from the German XETRA. One in EUR and one in USD. my %xetraquotes = $q->fetch("yahoo_europe","DBK.DE", "ERM.DE"); ok($xetraquotes{"DBK.DE","success"}); ok($xetraquotes{"DBK.DE","currency"} eq "EUR"); ok(($xetraquotes{"DBK.DE","currency"} eq "EUR") && !defined($xetraquotes{"DBK.DE","currency_set_by_fq"}));
From: fredrik.p.persson [...] gmail.com
Of course, no problem. I changed the program you provded slightly, to make it test Ftest_funds. Seems to work. It's very basic, not very extensive, but may be sufficient. Tell me if you want me to extend it, and if so, in what way. And also; "Ftest" is just short for "Fredrik test" which is probably a terrible name if you want to include this into finance quote. There's also no copyright/license text. The work is derived from SEB.pm and I'll agree to license my contribution into any license the finance quote maintainers see fit.
#!/usr/bin/perl -w use strict; use Test::More; use Finance::Quote; if (not $ENV{ONLINE_TEST}) { plan skip_all => 'Set $ENV{ONLINE_TEST} to run this test'; } plan tests => 9; # Test Ftest functions. my $q = Finance::Quote->new(); my $year = (localtime())[5] + 1900; my $lastyear = $year - 1; my %quotes = $q->ftest_funds("F0GBR069L2","BOGUS"); ok(%quotes); # Check the nav values are defined. These are the most # used and most reliable indicators of success. ok($quotes{"F0GBR069L2","price"} > 0); ok(length($quotes{"F0GBR069L2","name"}) > 0); ok($quotes{"F0GBR069L2","success"}); ok($quotes{"F0GBR069L2", "currency"} eq "USD"); ok(substr($quotes{"F0GBR069L2","isodate"},0,4) == $year || substr($quotes{"F0GBR069L2","isodate"},0,4) == $lastyear); ok(substr($quotes{"F0GBR069L2","date"},6,4) == $year || substr($quotes{"F0GBR069L2","date"},6,4) == $lastyear); # Make sure we don't have spurious % signs. ok($quotes{"F0GBR069L2","p_change"} !~ /%/); # Check that a bogus stock returns no-success. ok(! $quotes{"BOGUS","success"});