Module: YahooFinance
- Defined in:
- lib/yahoofinance.rb
Overview
Module for retrieving quote data (‘live’ and ‘historical’) from YahooFinance!
This module is made up of 2 parts:
1. Retrieving 'live' quote data. 'Live' quotes are the current
data available for a given stock. Most often delayed 20mins.
2. Retrieving 'historical' quote data. 'Historical' quotes are
for past pricings of a given stock.
Defined Under Namespace
Classes: BaseQuote, ExtendedQuote, HistoricalQuote, RealTimeQuote, StandardQuote
Constant Summary collapse
- STDHASH =
‘Live’ quote data retrieval.
{ "s" => [ "symbol", "val" ], "n" => [ "name", "val" ], "l1" => [ "lastTrade", "val.to_f" ], "d1" => [ "date", "val" ], "t1" => [ "time", "val" ], "c" => [ "change", "val" ], "c1" => [ "changePoints", "val.to_f" ], "p2" => [ "changePercent", "val.to_f" ], "p" => [ "previousClose", "val.to_f" ], "o" => [ "open", "val.to_f" ], "h" => [ "dayHigh", "val.to_f" ], "g" => [ "dayLow", "val.to_f" ], "v" => [ "volume", "val.to_i" ], "m" => [ "dayRange", "val" ], "l" => [ "lastTradeWithTime", "val" ], "t7" => [ "tickerTrend", "convert(val)" ], "a2" => [ "averageDailyVolume", "val.to_i" ], "b" => [ "bid", "val.to_f" ], "a" => [ "ask", "val.to_f" ] # These return integers like "1,000". The CVS parser gets confused by this # so I've removed them for the time being. # "b6" => [ "bidSize", "val" ], # "a5" => [ "askSize", "val" ] # "k3" => [ "lastTradeSize", "convert(val)" ], }
- EXTENDEDHASH =
{ "s" => [ "symbol", "val" ], "n" => [ "name", "val" ], "w" => [ "weeks52Range", "val" ], "j5" => [ "weeks52ChangeFromLow", "val.to_f" ], "j6" => [ "weeks52ChangePercentFromLow", "val" ], "k4" => [ "weeks52ChangeFromHigh", "val.to_f" ], "k5" => [ "weeks52ChangePercentFromHigh", "val" ], "e" => [ "earningsPerShare", "val.to_f" ], "r" => [ "peRatio", "val.to_f" ], "s7" => [ "shortRatio", "val" ], "r1" => [ "dividendPayDate", "val" ], "q" => [ "exDividendDate", "val" ], "d" => [ "dividendPerShare", "convert(val)" ], "y" => [ "dividendYield", "convert(val)" ], "j1" => [ "marketCap", "convert(val)" ], "t8" => [ "oneYearTargetPrice", "val" ], "e7" => [ "epsEstimateCurrentYear", "val" ], "e8" => [ "epsEstimateNextYear", "val" ], "e9" => [ "epsEstimateNextQuarter", "val" ], "r6" => [ "pricePerEPSEstimateCurrentYear", "val" ], "r7" => [ "pricePerEPSEstimateNextYear", "val" ], "r5" => [ "pegRatio", "val.to_f" ], "b4" => [ "bookValue", "val.to_f" ], "p6" => [ "pricePerBook", "val.to_f" ], "p5" => [ "pricePerSales", "val.to_f" ], "j4" => [ "ebitda", "val" ], "m3" => [ "movingAve50days", "val" ], "m7" => [ "movingAve50daysChangeFrom", "val" ], "m8" => [ "movingAve50daysChangePercentFrom", "val" ], "m4" => [ "movingAve200days", "val" ], "m5" => [ "movingAve200daysChangeFrom", "val" ], "m6" => [ "movingAve200daysChangePercentFrom", "val" ], "s1" => [ "sharesOwned", "val" ], "p1" => [ "pricePaid", "val" ], "c3" => [ "commission", "val" ], "v1" => [ "holdingsValue", "val" ], "w1" => [ "dayValueChange", "val" ], "g1" => [ "holdingsGainPercent", "val" ], "g4" => [ "holdingsGain", "val" ], "d2" => [ "tradeDate", "val" ], "g3" => [ "annualizedGain", "val" ], "l2" => [ "highLimit", "val" ], "l3" => [ "lowLimit", "val" ], "n4" => [ "notes", "val" ], "x" => [ "stockExchange", "val" ] # This returns an integer like "1,000,000". # The CVS parser gets confused by this # so I've removed it for the time being. # "f6" => [ "floatShares", "val" ], }
- REALTIMEHASH =
{ "s" => [ "symbol", "val" ], "n" => [ "name" , "val" ], "b2" => [ "ask", "val.to_f" ], "b3" => [ "bid", "val.to_f" ], "k2" => [ "change", "val" ], "k1" => [ "lastTradeWithTime", "val" ], "c6" => [ "changePoints", "val.to_f" ], "m2" => [ "dayRange", "val" ], "j3" => [ "marketCap", "convert(val)" ], # "v7" => [ "holdingsValue", "val" ], # "w4" => [ "dayValueChange", "val" ], # "g5" => [ "holdingsGainPercent", "val" ], # "g6" => [ "holdingsGain", "val" ], # "r2" => [ "pe", "val" ], # "c8" => [ "afterHoursChange", "val" ], # "i5" => [ "orderBook", "val" ], }
- DEFAULT_READ_TIMEOUT =
5
Class Method Summary collapse
-
.get(symbols, format, timeout = DEFAULT_READ_TIMEOUT) ⇒ Object
Return a string containing the results retrieved from YahooFinance.
- .get_extended_quotes(symbols) ⇒ Object
- .get_historical_quotes(symbol, startDate, endDate) ⇒ Object
- .get_historical_quotes_days(symbol, days, &block) ⇒ Object
- .get_HistoricalQuotes(symbol, startDate, endDate) ⇒ Object
- .get_HistoricalQuotes_days(symbol, days, &block) ⇒ Object
- .get_quotes(quote_class, symbols, &block) ⇒ Object
- .get_realtime_quotes(symbols) ⇒ Object
- .get_standard_quotes(symbols) ⇒ Object
- .retrieve_raw_historical_quotes(symbol, startDate, endDate) ⇒ Object
Class Method Details
.get(symbols, format, timeout = DEFAULT_READ_TIMEOUT) ⇒ Object
Return a string containing the results retrieved from YahooFinance. If there was an error during the execution of this method, the string “” is returned. In practice, this means that no *Quote objects will be created (empty hashes will be returned from get_*_quotes methods).
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
# File 'lib/yahoofinance.rb', line 164 def YahooFinance.get( symbols, format, timeout=DEFAULT_READ_TIMEOUT ) return "" if symbols == nil symbols = symbols.join( "," ) if symbols.class == Array symbols.strip! return "" if symbols == "" # Catch any exceptions that might occur here. Possible exceptions # are the read_timeout and... # # # Don't catch any exceptions! Just let them be thrown. # # begin Net::HTTP.start( "finance.yahoo.com", 80 ) { |http| http.read_timeout = timeout response = nil # begin # Timeout.timeout( 1 ) { response = http.get( "/d/quotes.csv?s=#{symbols}&f=#{format}&e=.csv" ) # } # rescue Exception => ex # puts "inner timeout got: #{ex.inspect}" # response = nil # end return "" if !response response.body.chomp } # rescue Exception => ex # This can often be a Timeout::Error. # puts "YahooFinance::get - #{ex.inspect}" # return "" # end end |
.get_extended_quotes(symbols) ⇒ Object
228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/yahoofinance.rb', line 228 def YahooFinance.get_extended_quotes( symbols ) csvquotes = YahooFinance::get( symbols, EXTENDEDHASH.keys.join ) ret = Hash.new CSV.parse( csvquotes ) do |row| qt = ExtendedQuote.new( row ) if block_given? yield qt end ret[qt.symbol] = qt end ret end |
.get_historical_quotes(symbol, startDate, endDate) ⇒ Object
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 |
# File 'lib/yahoofinance.rb', line 445 def YahooFinance.get_historical_quotes( symbol, startDate, endDate ) rows = [] rowct = 0 gotchunk = false # # Yahoo is only able to provide 200 data points at a time for Some # "international" markets. We want to download all of the data # points between the startDate and endDate, regardless of how many # 200 data point chunks it comes in. In this section we download # as many chunks as needed to get all of the data points. # begin gotchunk = false r = YahooFinance.retrieve_raw_historical_quotes( symbol, startDate, endDate ) if block_given? # If we were given a block, yield to it for every row of data # downloaded. r.each { |row| yield row } else rows += r end # Is this a chunk? if r.length == 200 # Adjust the endDate for when we retrieve the next chunk. endDate = HistoricalQuote.parse_date_to_Date( r.last[0] ) - 1 # Marke this as a chunk so do the download again with the new endDate. gotchunk = true end end while gotchunk if block_given? # If we have already yielded to every row, just return nil. return nil else # Otherwise return the big array of arrays. rows end end |
.get_historical_quotes_days(symbol, days, &block) ⇒ Object
489 490 491 492 493 |
# File 'lib/yahoofinance.rb', line 489 def YahooFinance.get_historical_quotes_days( symbol, days, &block ) endDate = Date.today() startDate = Date.today() - days YahooFinance.get_historical_quotes( symbol, startDate, endDate, &block ) end |
.get_HistoricalQuotes(symbol, startDate, endDate) ⇒ Object
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
# File 'lib/yahoofinance.rb', line 495 def YahooFinance.get_HistoricalQuotes( symbol, startDate, endDate ) ret = [] YahooFinance.get_historical_quotes( symbol, startDate, endDate ) { |row| if block_given? yield HistoricalQuote.new( symbol, row ) else ret << HistoricalQuote.new( symbol, row ) end } if block_given? return nil else return ret end end |
.get_HistoricalQuotes_days(symbol, days, &block) ⇒ Object
511 512 513 514 515 |
# File 'lib/yahoofinance.rb', line 511 def YahooFinance.get_HistoricalQuotes_days( symbol, days, &block ) endDate = Date.today() startDate = Date.today() - days YahooFinance.get_HistoricalQuotes( symbol, startDate, endDate, &block ) end |
.get_quotes(quote_class, symbols, &block) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/yahoofinance.rb', line 203 def YahooFinance.get_quotes( quote_class, symbols, &block ) if quote_class == YahooFinance::StandardQuote return get_standard_quotes( symbols, &block ) elsif quote_class == YahooFinance::ExtendedQuote return get_extended_quotes( symbols, &block ) elsif quote_class == YahooFinance::RealTimeQuote return get_realtime_quotes( symbols, &block ) else # Use the standard quote if the given quote_class was not recoginized. return get_standard_quotes( symbols, &block ) end end |
.get_realtime_quotes(symbols) ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/yahoofinance.rb', line 216 def YahooFinance.get_realtime_quotes( symbols ) csvquotes = YahooFinance::get( symbols, REALTIMEHASH.keys.join ) ret = Hash.new CSV.parse( csvquotes ) do |row| qt = RealTimeQuote.new( row ) if block_given? yield qt end ret[qt.symbol] = qt end ret end |
.get_standard_quotes(symbols) ⇒ Object
240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/yahoofinance.rb', line 240 def YahooFinance.get_standard_quotes( symbols ) csvquotes = YahooFinance::get( symbols, STDHASH.keys.join ) ret = Hash.new CSV.parse( csvquotes ) do |row| qt = StandardQuote.new( row ) if block_given? yield qt end ret[qt.symbol] = qt end ret end |
.retrieve_raw_historical_quotes(symbol, startDate, endDate) ⇒ Object
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/yahoofinance.rb', line 416 def YahooFinance.retrieve_raw_historical_quotes( symbol, startDate, endDate ) # Don't try to download anything if the starting date is before # the end date. return [] if startDate > endDate Net::HTTP.start( "itable.finance.yahoo.com", 80 ) { |http| query = "/table.csv?s=#{symbol}&g=d" + "&a=#{startDate.month-1}&b=#{startDate.mday}&c=#{startDate.year}" + "&d=#{endDate.month-1}&e=#{endDate.mday}&f=#{endDate.year.to_s}" #puts "#{query}" response = http.get( query ) #puts "#{response.body}" body = response.body.chomp # If we don't get the first line like this, there was something # wrong with the data (404 error, new data formet, etc). return [] if body !~ /Date,Open,High,Low,Close,Volume,Adj Close/ # Parse into an array of arrays. rows = CSV.parse( body ) # Remove the first array since it is just the field headers. rows.shift #puts "#{rows.length}" return rows } end |