anon
anon

Reputation:

Getting stock prices from Yahoo with Elisp?

I would like to use Yahoo to get stock prices from within an Emacs Lisp program. I have two questions.

  1. How do I make the http GET?
  2. What is the best what to store the data in Elisp so I can make comparisons of the data? In other words, should I use one hash table, several hash tables, or lists to represent that data returned from Yahoo?

Here's the basic outline of what I'd like to do.

;; Call Yahoo to get equity prices
;;
;; Yahoo Input: 
;;   http://download.finance.yahoo.com/d/quotes.csv?s=AAPL+GOOG&f=sb2b3jkm6
;; Yahoo Output:
;;  "AAPL",211.98,211.82,78.20,215.59,+17.90%
;;  "GOOG",602.94,601.69,282.75,629.51,+18.27%
;;
;; Symbol, ask, bid, 52 week low, 52 week high, % change from 200 day mavg
;;
;; Yahoo format described here: http://www.gummy-stuff.org/Yahoo-data.htm

(defun get-price-url (tickers)
"
s = symbol
b2 = ask real-time
b3 = bid real-time
j = 52 week low
k = 52 week high
"

  (concat "http://download.finance.yahoo.com/d/quotes.csv?s="
      (mapconcat 'identity tickers "+") "&f=sb2b3jk"))


(setq lst '("AAPL" "GOOG" "MSFT" "ORCL"))
(setq url (get-price-url lst))

;; Call Yahoo with Url, process results and place in a data structure
;; 

;; Return results sorted by largest change in 200 day mavg, in descending order
;;

Upvotes: 7

Views: 1805

Answers (2)

justinhj
justinhj

Reputation: 11316

Here's some code to get you started; I show how to grab the url to a buffer, parse each line and then display the ticker and price of each item. You can modify it from there to do what you need.

This parses each line of stock data into a list, and it's straight forward to grab the values using the first, second, third functions, or using nth. You can write functions to grab each element you want, such as get-ticker(quote) which would just return (first ticker)

I wouldn't over think what kind of data structure to use; whatever is easiest is fine. If you need high performance then you shouldn't be using emacs lisp for this anyway.

(defun test()
  (interactive)
  (let ((quotes (get-quotes '("AAPL" "GOOG" "MSFT" "ORCL" "ERTS" "THQI") "sb")))
    (show-quotes quotes)))

(defun show-quotes(quotes)
  (dolist (quote quotes)
    (message (format "%s $%.2f" (first quote) (string-to-number (second quote))))))

(defun get-quotes(tickers field-string)
  "Given a list of ticker names and a string of fields to return as above, this grabs them
from Yahoo, and parses them"
  (let ((results-buffer (get-yahoo-quotes-to-buffer (get-price-url tickers field-string))))
    (switch-to-buffer results-buffer)
    (parse-quote-buffer results-buffer)))

(defun get-price-url (tickers field-string)
  "Set up the get url"
  (concat "http://download.finance.yahoo.com/d/quotes.csv?s=" 
      (mapconcat 'identity tickers "+") 
      "&f=" field-string))

(defun get-yahoo-quotes-to-buffer(url)
  "Retrieve the quotes to a buffer and return it"
  (url-retrieve-synchronously url))

(defun parse-quote-buffer(b)
  "Parse the buffer for quotes"
  (goto-line 1)
  (re-search-forward "^\n")
  (beginning-of-line)
  (let ((res nil))
    (while (> (point-max) (point))
      (setf res (cons  (split-string (thing-at-point 'line) ",") res))
      (forward-line 1))
    (reverse res)))

Upvotes: 6

Jim Ferrans
Jim Ferrans

Reputation: 31012

Check out http://edward.oconnor.cx/elisp/. Edward has some examples of interacting with various services using HTTP, and if you can't find a Yahoo client library you could write one using these techniques.

Upvotes: 2

Related Questions