Getting Stock Prices from the Web

As the final step to complete our net asset application, we have to get the stock price from the web. We have the list of ticker symbols and the units in the file stocks.xml we saw earlier. For each of these symbols, we need to fetch the closing price. Thankfully, Yahoo provides a web service that we can use to get stock data. To find the latest closing price for Google stocks, for example, we can visit the following URL:

 
http://ichart.finance.yahoo.com/table.csv?s=GOOG&a=00&b=01&c=2015

The parameters s, a, b, and c represent the ticker symbol, start month (January is 0), start day, and start year, respectively. If you don’t specify the end dates using the parameters d, e, and f, the service returns all prices from the given start date until the most recent available date. When you visit the previous URL, you’ll get a comma-separated value (CSV) file to download.

A sample of the file is shown here:

 
Date,Open,High,Low,Close,Volume,Adj Close
 
2015-03-20,561.65,561.72,559.05,560.36,2585800,560.36
 
2015-03-19,559.39,560.80,556.15,557.99,1191100,557.99
 
2015-03-18,552.50,559.78,547.00,559.50,2124400,559.50
 
...

To get the latest closing price, we have to skip the first header line and step to the second line, containing the data for the most recent date. From among the comma-separated values, simply grab the fifth element—the element at index 4 starting the count with the traditional 0. Grab the 5th element if you want the closing price or grab the 7th element if you want the adjusted closing price.

Let’s put the Yahoo service to work. We’ll open our stocks.xml file, grab each symbol, and fetch the latest closing price for that ticker. We multiply the closing price we fetched by the number of units we have, and we get the total value for that stock. Total all those values, and we get to know the total worth of our investments.

Let’s write the code that populates a map with the ticker symbols and units present in the XML file. We’ll also write the code to fetch data from the Yahoo service into a singleton object named StockPriceFinder:

UsingScala/StockPriceFinder.scala
 
import​ java.util.Calendar
 
 
object​ StockPriceFinder {
 
def​ getLatestClosingPrice(symbol: ​String​) : Double = {
 
val​ url = ​"http://ichart.finance.yahoo.com/table.csv?s="​ +
 
symbol + ​"&a=00&b=01&c="​ + Calendar.getInstance().get(Calendar.YEAR)
 
val​ data = scala.io.Source.fromURL(url).mkString
 
val​ mostRecentData = data.split(​" "​)(1)
 
val​ closingPrice = mostRecentData.split(​","​)(4).toDouble
 
closingPrice
 
}
 
def​ getTickersAndUnits() = {
 
val​ stocksAndUnitsXML = scala.xml.XML.load(​"stocks.xml"​)
 
(Map[​String​, ​Int​]() /: (stocksAndUnitsXML ​"symbol"​)) {
 
(map, symbolNode) =>
 
val​ ticker = (symbolNode ​"@ticker"​).toString
 
val​ units = (symbolNode ​"units"​).text.toInt
 
map + (ticker -> units)
 
}
 
}
 
}

In the getLatestClosingPrice method, given a symbol, we go out to the Yahoo service and get the price data. Since the data is in CSV format, we split the data to extract the closing price. The closing price is finally returned from this method.

Since our ticker symbols and units are in stocks.xml, the getTickersAndUnits method reads this file and creates a map of ticker symbols and units. We saw in earlier sections how to accomplish this. It is the same code moved into the singleton object. Now we’re all set to fetch the data and compute the results. The code for that is shown here:

UsingScala/FindTotalWorthSequential.scala
 
object​ FindTotalWorthSequential ​extends​ App {
 
val​ symbolsAndUnits = StockPriceFinder.getTickersAndUnits
 
 
println(​"Ticker Units Closing Price($) Total Value($)"​)
 
 
val​ startTime = System.nanoTime()
 
val​ valuesAndWorth = symbolsAndUnits.keys.map { symbol =>
 
val​ units = symbolsAndUnits(symbol)
 
val​ latestClosingPrice = StockPriceFinder getLatestClosingPrice symbol
 
val​ value = units * latestClosingPrice
 
 
(symbol, units, latestClosingPrice, value)
 
}
 
 
val​ netWorth = (0.0 /: valuesAndWorth) { (worth, valueAndWorth) =>
 
val​ (_, _, _, value) = valueAndWorth
 
worth + value
 
}
 
val​ endTime = System.nanoTime()
 
 
valuesAndWorth.toList.sortBy { _._1 }.foreach { valueAndWorth =>
 
val​ (symbol, units, latestClosingPrice, value) = valueAndWorth
 
println(f​"$symbol%7s $units%5d $latestClosingPrice%15.2f $value%.2f"​)
 
}
 
 
println(f​"The total value of your investments is $$$netWorth%.2f"​)
 
println(f​"Took ${(endTime-startTime)/1000000000.0}%.2f seconds"​)
 
}

Let’s run the code and take a look at the output:

 
Ticker Units Closing Price($) Total Value($)
 
AAPL 200 125.90 25180.00
 
ADBE 125 77.36 9670.00
 
ALU 150 3.84 576.00
 
: : : :
 
TXN 190 59.28 11263.20
 
VRSN 200 64.75 12950.00
 
XRX 240 13.18 3163.20
 
The total value of your investments is $146473.80
 
Took 11.13 seconds

We first get the map of ticker symbols and units from the XML file using the StockPriceFinder’s getTickersAndUnits method, and store it in the variable symbolsAndUnits. Then, for each symbol, we request the StockPriceFinder’s getLatestClosingPrice method to get the latest price. The result of the map operation is a collection of tuples with four values each: symbol, units, latestClosingPrice, and value of the stock. We then use the foldLeft method’s alternate method /: to reduce the collection of tuples to a single value of netWorth. This concludes the computation part of the code and we’re ready to print the results after this. To ensure the output appears in a sorted order by the ticker symbols, we convert the collection of tuples into a list using toList and sort it by the symbol names—this is the first value in the tuple, indicated by the ._1 indexed property. We print the units, price, and value for each symbol, then the net worth, and finally the time the code took to run.

We didn’t need much code to accomplish the task. The example took about 11 seconds to run. In the next section, we’ll make it respond faster.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.134.99.32