GreatWebGuy

Self-proclaimed greatness is a hard thing to prove

Stock quote and chart from Yahoo in Java

I was recently in need of a stock quote web service in order to display quote information and charts for a corporate website I was working on, so I started looking around for something, free of course. I kept reading that the most common example of web as a service is the stock quote example, but I didn’t really find any examples that gave me a warm and fuzzy, everyone seemed to be scraping the html from a page. Doesn’t seem to be much out there, in the way of quote services for free, but I did come across a yahoo download service and a few half written examples, where you can fetch quote information from Yahoo in .csv format, with a 20 minute delay of course. I’ve also added a 1-day small chart and a 5-day large chart image by passing the symbol into Yahoo’s basic chart image url.

StockTickerDAO.java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class StockTickerDAO {
	private static final Log log = LogFactory.getLog(StockTickerDAO.class);
	private static final StockTickerDAO stockDAO = new StockTickerDAO();
	private static HashMap<String, StockBean> stocks = new HashMap<String, StockBean>();
	private static final long TWENTY_MIN = 1200000;

	private StockTickerDAO() {}

	public static StockTickerDAO getInstance() {
		return stockDAO;
	}

	/**
	 *
	 * @param symbol
	 * @return StockBean
	 * will return null if unable to retrieve information
	 */
	public StockBean getStockPrice(String symbol) {
		StockBean stock;
		long currentTime = (new Date()).getTime();
		// Check last updated and only pull stock on average every 20 minutes
		if (stocks.containsKey(symbol)) {
			stock = stocks.get(symbol);
			if(currentTime - stock.getLastUpdated() > TWENTY_MIN) {
				stock = refreshStockInfo(symbol, currentTime);
			}
		} else {
			stock = refreshStockInfo(symbol, currentTime);
		}
		return stock;
	}

	//This is synched so we only do one request at a time
	//If yahoo doesn't return stock info we will try to return it from the map in memory
	private synchronized StockBean refreshStockInfo(String symbol, long time) {
		try {
			URL yahoofin = new URL("http://finance.yahoo.com/d/quotes.csv?s=" + symbol + "&f=sl1d1t1c1ohgv&e=.csv");
			URLConnection yc = yahoofin.openConnection();
			BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				String[] yahooStockInfo = inputLine.split(",");
				StockBean stockInfo = new StockBean();
				stockInfo.setTicker(yahooStockInfo[0].replaceAll("\"", ""));
				stockInfo.setPrice(Float.valueOf(yahooStockInfo[1]));
				stockInfo.setChange(Float.valueOf(yahooStockInfo[4]));
				stockInfo.setChartUrlSmall("http://ichart.finance.yahoo.com/t?s=" + stockInfo.getTicker());
				stockInfo.setChartUrlLarge("http://chart.finance.yahoo.com/w?s=" + stockInfo.getTicker());
				stockInfo.setLastUpdated(time);
				stocks.put(symbol, stockInfo);
				break;
			}
			in.close();
		} catch (Exception ex) {
			log.error("Unable to get stockinfo for: " + symbol + ex);
		}
		return stocks.get(symbol);
     }
}

StockBean.java

public class StockBean {
	String ticker;
	float price;
	float change;
	String chartUrlSmall;
	String chartUrlLarge;
	long lastUpdated;
	public String getTicker() {
		return ticker;
	}
	public void setTicker(String ticker) {
		this.ticker = ticker;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public float getChange() {
		return change;
	}
	public void setChange(float change) {
		this.change = change;
	}
	public String getChartUrlSmall() {
		return chartUrlSmall;
	}
	public void setChartUrlSmall(String chartUrlSmall) {
		this.chartUrlSmall = chartUrlSmall;
	}
	public String getChartUrlLarge() {
		return chartUrlLarge;
	}
	public void setChartUrlLarge(String chartUrlLarge) {
		this.chartUrlLarge = chartUrlLarge;
	}
	public long getLastUpdated() {
		return lastUpdated;
	}
	public void setLastUpdated(long lastUpdated) {
		this.lastUpdated = lastUpdated;
	}
}

Using it

StockBean  stock = StockTickerDAO.getInstance().getStockPrice("GOOG");

Comments