Skip Menu |

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

Report information
The Basics
Id: 76951
Status: new
Priority: 0/
Queue: Finance-Quote

People
Owner: Nobody in particular
Requestors: pratzlaff [...] cfa.harvard.edu
Cc:
AdminCc:

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



Subject: Finance::Quote::FidelityFixed, a new submodule for individual bond quotes
The attached file scrapes the Fidelity fixed income site to retrieve quotes for a bond, given its CUSIP number.
Subject: FidelityFixed.pm
#!/usr/bin/perl -w # # FidelityFixed.pm # package Finance::Quote::FidelityFixed; require 5.004; # # Modification of Rolf Endres' Finance::Quote::ZA # # Peter Ratzlaff <pratzlaff@gmail.com> # May, 2012 # $VERSION = '1.17'; use strict; use vars qw /$VERSION/ ; use LWP::UserAgent; use HTTP::Request::Common; use HTML::TableExtract; # e.g., http://fixedincome.fidelity.com/fi/FIIndividualBondsSearch?cusip=912810QT8 my $FIDELITY_MAINURL = ("http://fixedincome.fidelity.com/"); my $FIDELITY_URL = ($FIDELITY_MAINURL."fi/FIIndividualBondsSearch?cusip="); sub methods { return (fidelityfixed => \&fidelityfixed); } sub labels { my @labels = qw/ method source name symbol coupon bid bidyield askyield ask date isodate time 3rdparty price /; return (fidelityfixed => \@labels); } sub fidelityfixed { my $quoter = shift; my @symbols = @_; my %info; my ($te, $ts, $row); my @rows; return unless @symbols; my $ua = $quoter->user_agent; foreach my $symbol (@symbols) { my $url = $FIDELITY_URL.$symbol; #print "[debug]: ", $url, "\n"; my $response = $ua->request(GET $url); #print "[debug]: ", $response->content, "\n"; if (!$response->is_success) { $info{$symbol, "success"} = 0; $info{$symbol, "errormsg"} = "Error contacting URL"; next; } $te = new HTML::TableExtract(); $te->parse($response->content); #print "[debug]: (parsed HTML)",$te, "\n"; unless ($te->first_table_found()) { #print STDERR "no tables on this page\n"; $info{$symbol, "success"} = 0; $info{$symbol, "errormsg"} = "Parse error"; next; } # Debug to dump all tables in HTML... =begin comment print "\n \n \n \n[debug]: ++++ ==== ++++ ==== ++++ ==== ++++ ==== START OF TABLE DUMP ++++ ==== ++++ ==== ++++ ==== ++++ ==== \n \n \n \n"; foreach $ts ($te->table_states) {; printf "\n \n \n \n[debug]: //// \\\\ //// \\\\ //// \\\\ //// \\\\ START OF TABLE %d,%d //// \\\\ //// \\\\ //// \\\\ //// \\\\ \n \n \n \n", $ts->depth, $ts->count; foreach $row ($ts->rows) { print '[debug]: ', join('|', @$row), "\n"; } } print "\n \n \n \n[debug]: ++++ ==== ++++ ==== ++++ ==== ++++ ==== END OF TABLE DUMP ++++ ==== ++++ ==== ++++ ==== ++++ ==== \n \n \n \n"; =cut # GENERAL FIELDS $info{$symbol, "method"} = "fidelityfixed"; $info{$symbol, "symbol"} = $symbol; $info{$symbol, "source"} = $FIDELITY_MAINURL; # OTHER INFORMATION $ts = $te->table_state(0,1); if($ts) { (@rows) = $ts->rows; my $n = 3; if ($rows[$n][1] =~ /fidelity is not currently offering this security/i) { $n = 4; } if ( $rows[$n][1] !~ /do not match/ and $rows[$n][1] !~ /return to the previous page/ and 1 ) { $info{$symbol, 'success'} = 1; $info{$symbol, 'name'} = $rows[$n][1]; $info{$symbol, 'coupon'} = $rows[$n][2]; $info{$symbol, 'maturity'} = $rows[$n][3]; $info{$symbol, 'bidyield'} = $rows[$n][6]; $info{$symbol, 'bid'} = $rows[$n][7]; $info{$symbol, 'ask'} = $rows[$n][8]; $info{$symbol, 'askyield'} = $rows[$n][9]; $info{$symbol, '3rdparty'} = $rows[$n][10]; # some bonds have a "Depth of Book" column in the table $info{$symbol, '3rdparty'} = $rows[$n][11] unless $info{$symbol, '3rdparty'} =~ /\d+\.\d+/; #$info{$symbol, 'price'} = sprintf("%.2f", 0.5*($info{$symbol,'bid'} + $info{$symbol,'ask'})); $info{$symbol, 'currency'} = 'USD'; # clean things up a bit $info{$symbol, 'name'} =~ s/^\s+//; $info{$symbol, 'name'} =~ s/\s+$//; # ($_) = /(\d+\.\d+)/ for $info{$symbol, 'bid'}, $info{$symbol, 'ask'}; ($info{$symbol, $_}) = $info{$symbol, $_} =~ /(\d+\.\d+)/ for qw( bid ask 3rdparty bidyield askyield ); $info{$symbol, 'price'} = $info{$symbol, '3rdparty'}; if ($response->content =~ /As of (\d+)\/(\d+)\/(\d+) at (\d+)\:(\d+) ([ap])\.m\./) { $info{$symbol, 'date'} = "$1/$2/$3"; $info{$symbol, 'isodate'} = "$3-$1-$2"; $info{$symbol, 'time'} = $6 eq 'a' ? "$4:$5" : ($4+12).":$5"; } } else { $info{$symbol, "errormsg"} = "no match"; } }; } return wantarray() ? %info : \%info; } 1; =head1 NAME Finance::Quote::FidelityFixed- Obtain individual bond quotes from Fidelity =head1 SYNOPSIS use Finance::Quote; $q = Finance::Quote->new; # Don't know anything about failover yet... =head1 DESCRIPTION This module obtains individual bond quotes by CUSIP number from fixedincome.fidelity.com =head1 LABELS RETURNED Information available from FidelityFixed may include the following labels: method source name symbol coupon bid bidyield askyield ask price=3rdparty date isodate time =head1 SEE ALSO fidelity.com Finance::Quote =cut