Bargain Hunter

Programming Snapshot – Stock Quote API

Article from Issue 210/2018
Author(s):

Financial wizard Mike Schilli is annoyed that some web services have discontinued serving up real-time stock market data. To keep an eye on his investment dollars, Mike taps into a little known interface for stock prices.

For users of stock-quote-serving APIs, the fruit is currently hanging higher. First, Google discontinued its web service [1] for real-time stock market data (Figure 1); then, Yahoo followed suit and pulled the plug. With the end of their undocumented but widely used share price interface in CSV format [2], Yahoo, perhaps unknowingly, also pulled the rug from under a number of open source projects, such as the Perl Yahoo::Finance CPAN module and the Python yahoo-finance package. A few open source portfolio-tracking applications using these popular packages were dragged into the abyss along with them.

Figure 1: Google's financial site for portfolio tracking has seen better days.

On the GitHub sites of these projects, the Issues tabs are now overflowing with comments, there's quite a bit of wailing and gnashing of teeth from users, and much wringing of hands of those who hope to find a replacement for the vanished free real-time (or at least time-delayed) stock market price data source.

Free Is Cheap Enough

For a hefty monthly fee, of course, you can find dozens of business-level stock market data providers, such as Bloomberg, but only a few competitors offer free quotes, often only to registered users who are adding an issued API key to every request. It is probably only a matter of time before the free source presented today also dries up, but I'm working on the assumption that, in the future, options for retrieving the data free of charge will still be around.

Developers should therefore be prepared for the fact that an application's data back end can change at short notice. Thanks to a design abstracting away the share price source, this should be easy to handle with a simple upgrade of the quote library for applications; the caravan of thirsty camels, after only finding dried out water holes at the old oasis, will move on to more refreshing destinations.

Listing 1 [3] uses a still open Yahoo source to obtain the current market prices of equities on the world's major stock exchanges. For example, the amzn ticker symbol in dollars reveals the daily value of the Amazon share on the New York Stock Exchange. Those who want to explore Amazon's share price on the German Xetra Stock Exchange in euros enter amz.de instead.

Listing 1

myquote.py

 

To do this, the quote() function awaits the ticker symbol and sends a request to the web API that returns a data structure encoded in JSON. Under the regularMarketPrice key is the numerical value for the price in the currency customary on the market where it is traded.

Cash Check in the Money Bin

Banks and stock brokerage houses offer portfolio management functions and calculate the net value of the deposit for their clients. Google and Yahoo also offer portfolios, although they are in the process of change [2]; both seem to be looking for new ways to make money off the service somehow.

The advantage of a home-grown script is that it adds all items across accounts or brokerages. For this purpose, the user has to keep a YAML file with the items in their portfolio up to date manually, as shown in Listing 2. However, this approach preserves the investors' privacy more reliably than third-party applications that have a monetary interest in mining user data and using it for marketing purposes or, worse, selling it to the highest bidder.

Listing 2

portfolio.yaml

 

Listing 2 shows two fictitious accounts, one at Wells Fargo and one at Citibank, with 100 Amazon and 50 Google shares, the latter of which are now traded under the "Alphabet" name, although the company's ticker symbol on Nasdaq is still goog. Both accounts also have a Cash item. The mymoney.py script in Listing 3 adds the cash at face value but determines the current value of the share items via the API and multiplies the stock price by the number of shares in the deposit.

Listing 3

mymoney.py Calculations

 

To perform this calculation, Listing 4 (line 3) includes the yaml module, which you must have installed previously by typing:

pip install --user pyyaml

Listing 4

mymoney.py

 

It provides the load() method used in line 8 to parse the account data from the portfolio file in Listing 2. Line 30 iterates across the accounts found; line 32 iterates across the items stored therein. In the current version, the script supports cash (cash) and shares (stock) but could easily be extended to include bonds, options, or items in foreign currencies, whose exchange rate the script then can retrieve in a similar fashion at run time. The cash_dump() function from line 18 determines the value of a cash item. There's no magic being performed here; it only returns a tuple with the name Cash and the amount.

To determine the value of a stock item, on the other hand, Listing 4 uses the myquote.py module from Listing 1 and calls its quote() function with the ticker symbol as a parameter. It multiplies the returned market price by the number of shares in the securities account and feeds this back to the main program together with a table key, all wrapped into a tuple. The main program only needs to add the line items across all accounts and output the total net value for the user (Listing 3).

Rounding, but Correctly

One thing to keep in mind is that computers are notoriously bad at adding floating-point numbers. If you add 1.23 and 4.56 together, you may get a result that deviates from the expected value of 5.79, because the CPU does not represent 1.23 exactly as 1 and 23 hundredths, but approximates it in binary format. In a past article, I discussed how even eBay can't add properly and that their monthly bill regularly is off by a few cents [4].

When it comes to adding money amounts, it is smarter to compute in cents rather than dollars. In other words, simply multiply the dollar amount by 100 and add it as a rounded integer; when displaying the result, inject a decimal point in front of the last two digits – Listing 4 does just that.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Perl: Portfolio Watch

    We'll show you a Perl script that helps you draw area graphs to keep track of your portfolio's performance.

  • Perl: Personal Finances

    A helpful Perl script gives you an immediate overview of your financial status, adding the balances of multiple accounts and share depots. It even allows users to add their own plugins.

  • Perl: PerlPanel

    One panel has a neat collection of applets and another has spectacular looks – but a combination of the two is rare. Now help draws nigh for the desktop: PerlPanel is extensible with do-it-yourself widgets.

  • Perl: Cucumber

    The Cucumber test framework helps developers and product departments jointly formulate test cases, not as program code, but in plain English. The initially skeptical Perlmeister has acquired a taste for this.

  • GnuCash 3.5

    Put your personal finances in order or manage your small business with GNUCash 3.5, a free and open source software program designed to handle both basic and complex accounting data.

comments powered by Disqus

Direct Download

Read full article as PDF:

Price $2.95

News