Subject: | Yahoo converts London pound prices to pence |
Problem: Yahoo assumes all London prices are quoted in pence
To reproduce:
1) Use finance::quote to get a price for LTI.L (e.g. gnc-fq-dump yahoo LTI.L for those with
gnucash)
2) Check price against yahoo finance page
3) Note finance::quote price is 100x smaller than it should be
Problem: yahoo_request() assumes that the Yahoo currency code of 'GBp' is an error, changes
it to GBP, and also notes that Yahoo reports London prices in pence, so multiplies the prices
by 100.
In reality Yahoo reports some London prices in pence with currency code GBp, and some in
pounds with currency code GBP.
The attached patch fixes this by handling the price conversion to pence first, and only where
the currency code is GBp or GBX, (leaving GBP in pounds), and then fixes the currency code to
match the conversion that has been made.
Outstanding issue: the code noted that in November 2008 Yahoo started reporting prices
with currency code 'GBX' - I can't find any of these at the moment, so I've assumed that GBX
means pence. This assumption means that prices coded GBX will not change when this patch
is applied, but it isn't tested, because until Yahoo throws me a GBX-coded price I can't see
whether it's actually pounds or pence. For what it is worth Wikipedia suggests that GBX is a
code for pence sterling.
Subject: | patch.Base.pm |
--- Base.pm 2009-04-13 15:15:29.000000000 +0100
+++ modifiedbase.pm 2009-05-16 11:26:03.000000000 +0100
@@ -250,10 +250,28 @@
$info{$symbol,"time"} = $quoter->isoTime($info{$symbol,"time"});
}
+ # Convert prices (when needed). E.G. Some London sources
+ # return in pence. Yahoo denotes this with GBP vs GBp
+ # We'd like them to return in pounds (divide by 100).
+ if (defined($exchange)) {
+ if (($exchange eq "L" &&
+ (($info{$symbol,"currency"} eq "GBp") ||
+ #Assume GBX also quoted in pence; if not remove next line
+ ($info{$symbol,"currency"} eq "GBX"))) ||
+ ($exchange eq "TA")) {
+ foreach my $field ($quoter->default_currency_fields) {
+ next unless ($info{$symbol,$field});
+ $info{$symbol,$field} =
+ $quoter->scale_field($info{$symbol,$field},0.01);
+ }
+ }
+ # Other exchanges here as needed.
+ }
+
+
if (defined($info{$symbol,"currency"})) {
- # Convert the currency to be all uppercase for
- # backward compatability. Needed because Yahoo
- # returns GBP as GBp. There may be others.
+ # Having converted London prices to GBP above we
+ # make lower-case and turn GBX to GBP.
$info{$symbol,"currency"} =~ tr/a-z/A-Z/;
# yahoo started to return GBX instead of GBP
# somewhere arround 9 oct 2008.
@@ -274,20 +292,6 @@
$info{$symbol,"currency_set_by_fq"} = 1;
}
- # Convert prices (when needed). E.G. London sources
- # return in pence. We'd like them to return in pounds
- # (divide by 100).
- if (defined($exchange)) {
- if (($exchange eq "L" && $info{$symbol,"currency"} eq "GBP") ||
- ($exchange eq "TA")) {
- foreach my $field ($quoter->default_currency_fields) {
- next unless ($info{$symbol,$field});
- $info{$symbol,$field} =
- $quoter->scale_field($info{$symbol,$field},0.01);
- }
- }
- # Other exchanges here as needed.
- }
} # End of processing each stock line.
} # End of lookup loop.