Finance.Quote.Yahoo
Finance.Quote.Yahoo is a module to obtain quote information from finance.yahoo.com, which delivers a csv file with data for various fields, which are documented at http://www.gummy-stuff.org/Yahoo-data.htm.
The homepage for this module is http://www.b7j0c.org/stuff/haskell-yquote.xhtml
The license for this module is at http://www.b7j0c.org/stuff/license.txt
Since this uses Data.Time.Format, ghc-6.6.1 or greater is required.
Error reporting is somewhat of a mixed model in this module. Where strict errors of data construction occur, these will be noted as fatal error() signals, so the error can be noted and fixed. An example of this would be putting the start and end data in the wrong order for the retrieval of historical quotes or the creation of a malformed URI. On the other hand, I continue to propogate Nothing() for networking issues as there may be external issues creating these errors for which one may want program execution to continue. My personal tendency is to fail early when possible and practical.
Exported functions:
getQuote, which takes a list of quote symbols (in the finance sense of "symbol" - YHOO,GOOG etc), a list of fields, and returns a Data.Map, where the keys are pairs (symbol,field) and values are the returned Strings. Upon any problem, Nothing is returned. I have not cast the data into stronger types than String since Yahoo is inconsistent about what is returned in the csv. Fields often contain punctuation, symbols, as well as numbers. So really, they are Strings.
getHistoricalQuote, which takes a quote symbol, and two Data.Time.Calendar Day types, one for the starting date to receive quote data, and one for the end date. Yahoo does not let you choose the fields to see in historical quotes, data is limited to price and volume information.
quoteRec - useful for debugging the quote URI to see if Yahoo is denying the service.
Here is small complete program illustrating the use of this module
module Main where import Finance.Quote.Yahoo import Data.Time.Calendar import Data.Map quoteSymbolList = ["YHOO","^DJI"] :: [QuoteSymbol] quoteFieldsList = ["s","l1","c"] :: [QuoteField] main = do q <- getQuote quoteSymbolList quoteFieldsList case q of Nothing -> error "no map" Just m -> case (Data.Map.lookup ("YHOO","l1") m) of Nothing -> print "no match" Just a -> print a let startDate = Data.Time.Calendar.fromGregorian 2007 07 01 let endDate = Data.Time.Calendar.fromGregorian 2007 07 03 h <- getHistoricalQuote (head quoteSymbolList) startDate endDate Daily case h of Nothing -> error "no historical" Just l -> sequence $ Prelude.map print l return ()
- getQuote :: [QuoteSymbol] -> [QuoteField] -> IO (Maybe (Map (QuoteSymbol, QuoteField) QuoteValue))
- getHistoricalQuote :: QuoteSymbol -> Day -> Day -> QuoteFrequency -> IO (Maybe [HistoricalQuote])
- defaultQuoteFields :: [QuoteField]
- baseQuoteURI :: String
- baseHistoricalURI :: [Char]
- quoteReq :: [QuoteSymbol] -> [QuoteField] -> String
- type QuoteField = String
- type QuoteSymbol = String
- type QuoteValue = String
- type Quote = [(QuoteField, QuoteValue)]
- type QuoteCurrency = Float
- data QuoteFrequency
- data HistoricalQuote = HistoricalQuote {
- symbol :: QuoteSymbol
- date :: Day
- open :: QuoteCurrency
- high :: QuoteCurrency
- low :: QuoteCurrency
- close :: QuoteCurrency
- adjclose :: QuoteCurrency
- volume :: Int
Documentation
getQuote :: [QuoteSymbol] -> [QuoteField] -> IO (Maybe (Map (QuoteSymbol, QuoteField) QuoteValue))Source
getQuote will take a list of symbols, a list of fields, and will return a Data.Map, where the key type is (symbol,field) and the value type is whatever quote value string is returned. An example map entry:
key: ("YHOO","c"), value: "24.00"
Which gives you the closing price (c) for the symbol YHOO.
NOTE! This function does NOT alter the casing of the quote symbols passed in the first parameter. These symbols are used as the first element of the Map key tuple without altering them. Be careful! This function is exported.
getHistoricalQuote :: QuoteSymbol -> Day -> Day -> QuoteFrequency -> IO (Maybe [HistoricalQuote])Source
getHistoricalQuote takes a stock symbol, start and end date ranges, a quote frequency setting, and obtains the HistoricalQuote lines for this given date range and quote frequency. Supported frequencies are Daily, Weekly, Monthly or Dividend. Hopefully these are self-explanatory. Nothing is returned on any error, but note if you ask for the quotes based on Dividend frequency for a stock that pays no dividends, you will not see Nothing, but just an empty result. Check finance.yahoo.com to see how far they offer quote history for a symbol you are interested in. Note! Yahoo takes some liberties with dates due to weekends and holidays and market closures. Exported.
Here is what a sample result looks like for one day in the history:
HistoricalQuote {symbol = "YHOO", date = 2007-07-02, open = 27.19, high = 27.27, low = 26.76, close = 26.86, adjclose = 26.86, volume = 21011000}
quoteReq :: [QuoteSymbol] -> [QuoteField] -> StringSource
This is the base uri to get csv quotes. Exported.
If you just want the name, latest price and change, use this. Exported.
quoteReq will build a String representation of a Yahoo Finance CSV request URI.
type QuoteField = StringSource
type QuoteSymbol = StringSource
type QuoteValue = StringSource
type Quote = [(QuoteField, QuoteValue)]Source
type QuoteCurrency = FloatSource
This is the base uri to get csv historical quote data. Exported.
Float is not an fully appropriate currency type, beware. Exported.
data QuoteFrequency Source
QuoteFrequency - frequency for historical quotes. Exported.
data HistoricalQuote Source
HistoricalQuote reflects the row form of a yahoo historical quote: Date,Open,High,Low,Close,Volume,Adj Close (taken from the csv itself). Exported.
HistoricalQuote | |
|