yahoo-finance 0.2.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c6a015a18c3319e26d41dbacde9bf2d76c5db9bf
4
- data.tar.gz: 9cde1310a1f8aa6585f1907a5300b732a3177410
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZjBkYTA4YjE1ZDQ5ODNhMTJiYmQ5YWM2ZDRhMTdkOTlhMmJkYzY5Yw==
5
+ data.tar.gz: !binary |-
6
+ NDAyNTI1YWQ5ZWNhNDJhMTAyYjNjMzQ5OWJmZWI5MTdjMWE2NGQ2NQ==
5
7
  SHA512:
6
- metadata.gz: 451ea63a655451a65a446c4d8596b32907140d9b01fbfd83353fbf1c401bc334e521eaa873caff4defdaae6348ecac853c959796efb4ff6270d0e4a8548fa4ce
7
- data.tar.gz: 95647240723348756960cab2ecd423b9df7f98f50b5414fba507a17b1c7bb876bf1c77c0f17943abdd927f6d66221167dd3f8c87eb136f55586fe09bbfca4c65
8
+ metadata.gz: !binary |-
9
+ ODUwYTM3YjI3OGNhYzFmZjRiZjFjMDYyMGU5N2M3YmJjMDZjNGQxZTc5OTg3
10
+ NDM2ZjRiNWI5YjNiYjU0ODRiZDRlZTkwMzJiNzM2ZmQ4MWI4M2I1ZTRhODM5
11
+ NzAxYmJiZGU1ZTJmZGMzZDA3OTFlYzZhN2ZmZTRjMDJiNDE1Njg=
12
+ data.tar.gz: !binary |-
13
+ NjFjZWY4MTc5YzMxNTIyMDU2ZGJhODc1ZTE2NDQ0ZDc2NzQ5NTU4MmJjNTA1
14
+ Y2FjZDFjMzYyYWRhZWM5YzBiZDFkYmUyNTFlNWQ2NDQ1NjJmNWI5YzEzYjAz
15
+ NjFjYWM0ZWQ1M2Q3ODIwMDZjZGVhZTI1YTk4MDBjMDk2YWZlODM=
data/HISTORY CHANGED
@@ -1,3 +1,13 @@
1
+ 1.2.0 - Feb 04, 2017
2
+ ====================
3
+ * Fixed support for { raw: false }
4
+ * Symbols that are not found will now not return (instead of returning a struct with an empty :symbol field and a bunch of "N/A"s)
5
+ * The returned quotes now will always include the :symbol name
6
+
7
+ 0.3.0 - Aug 16, 2015
8
+ ====================
9
+ * Refactorings & support for US companies data (via NASDAQ's Apis) - by Eric D. Santos Sosa
10
+
1
11
  0.2.0 - Nov 24, 2014
2
12
  ====================
3
13
  * Allow fetching a single symbol with the `quote` method
@@ -16,4 +26,4 @@
16
26
 
17
27
  0.0.1 - Aug 04, 2007
18
28
  ===============================
19
- * Initial implementation - no bells, no whristles :)
29
+ * Initial implementation - no bells, no whistles :)
data/README.md CHANGED
@@ -3,11 +3,10 @@ A dead simple wrapper for yahoo finance quotes end-point.
3
3
 
4
4
  ## Installation:
5
5
 
6
- `gem install 'yahoo-finance'`
7
- `require 'yahoo_finance'`
6
+ Just add it to your `Gemfile`:
7
+
8
+ `gem 'yahoo-finance'`
8
9
 
9
- If using bundler:
10
- `gem 'yahoo-finance', require: 'yahoo_finance'`
11
10
 
12
11
  ## Usage:
13
12
 
@@ -16,7 +15,8 @@ If using bundler:
16
15
  Pass an array of valid symbols (stock names, indexes, exchange rates) and a list of fields you want:
17
16
 
18
17
  ```ruby
19
- data = YahooFinance.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date])
18
+ yahoo_client = YahooFinance::Client.new
19
+ data = yahoo_client.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date])
20
20
  ```
21
21
 
22
22
  Data is now an array of results. You now have accessor methods to retrieve the data, with the return results being strings:
@@ -28,13 +28,28 @@ puts data[0].symbol + " value is: " + data[0].ask
28
28
  Passing `raw: false` will return numerical values
29
29
 
30
30
  ```ruby
31
- data = YahooFinance.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date], { raw: false } )
32
- data[0].ask # This is now a float
31
+ yahoo_client = YahooFinance::Client.new
32
+ data = yahoo_client.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date], { raw: false } )
33
+ data[0].ask # This is now a BigDecimal
34
+ ```
35
+
36
+ Passing `na_as_nil: true` will convert "N/A" responses to `nil`
37
+
38
+ ```ruby
39
+ yahoo_client = YahooFinance::Client.new
40
+
41
+ data = yahoo_client.quotes(["BVSP"], [:ask] )
42
+ data[0].ask
43
+ > "N/A"
44
+
45
+ data = yahoo_client.quotes(["BVSP"], [:ask], { na_as_nil: true } )
46
+ data[0].ask
47
+ > nil
33
48
  ```
34
49
 
35
50
  The full list of fields follows:
36
51
 
37
- ``` ruby
52
+ ```ruby
38
53
  :after_hours_change_real_time
39
54
  :annualized_gain
40
55
  :ask
@@ -112,6 +127,8 @@ The full list of fields follows:
112
127
  :price_paid
113
128
  :price_per_book
114
129
  :price_per_sales
130
+ :revenue
131
+ :shares_outstanding
115
132
  :shares_owned
116
133
  :short_ratio
117
134
  :stock_exchange
@@ -123,6 +140,30 @@ The full list of fields follows:
123
140
  :weeks_range_52
124
141
  ```
125
142
 
143
+ ### Getting symbols by stock market (beta)
144
+
145
+ Create a YahooFinance::Client instance
146
+
147
+ ```ruby
148
+ yahoo_client = YahooFinance::Client.new
149
+ ```
150
+
151
+ Calling symbols_by_market method (symbols_by_market(country, stock_market))
152
+
153
+ Note: Can only be called with US Stock Markets for now.
154
+
155
+ *Important: This data comes directly from NASDAQ's CSV endpoints, NOT Yahoo Finance*. It might be extracted into a different Gem in the future.
156
+
157
+ ```ruby
158
+ yahoo_client.symbols_by_market('us', 'nyse') # Only US Stock Markets For Now
159
+ ```
160
+
161
+ This method returns an array of symbols that can be used with the quotes method
162
+
163
+ ```ruby
164
+ data = yahoo_client.quotes(yahoo_client.symbols_by_market('us', 'nyse'), [:ask, :bid, :last_trade_date])
165
+ ```
166
+
126
167
  ### Getting historical quotes
127
168
 
128
169
  Here you can specify a date range and a symbol, and retrieve historical data for it.
@@ -130,19 +171,22 @@ The last parameter (options) can include, besides the "raw" option, a "period" o
130
171
  The period can be specified as :daily, :monthly, :weekly or :dividends_only
131
172
 
132
173
  ```ruby
133
- data = YahooFinance.historical_quotes("AAPL") # entire historical data
174
+ yahoo_client = YahooFinance::Client.new
175
+ data = yahoo_client.historical_quotes("AAPL") # entire historical data
134
176
  ```
135
177
 
136
178
  or
137
179
 
138
180
  ```ruby
139
- data = YahooFinance.historical_quotes("AAPL", { start_date: Time::now-(24*60*60*10), end_date: Time::now }) # 10 days worth of data
181
+ yahoo_client = YahooFinance::Client.new
182
+ data = yahoo_client.historical_quotes("AAPL", { start_date: Time::now-(24*60*60*10), end_date: Time::now }) # 10 days worth of data
140
183
  ```
141
184
 
142
185
  or
143
186
 
144
187
  ``` ruby
145
- data = YahooFinance.historical_quotes("AAPL", { raw: false, period: :monthly })
188
+ yahoo_client = YahooFinance::Client.new
189
+ data = yahoo_client.historical_quotes("AAPL", { raw: false, period: :monthly })
146
190
  ```
147
191
 
148
192
  ### Getting splits
@@ -150,7 +194,8 @@ data = YahooFinance.historical_quotes("AAPL", { raw: false, period: :monthly })
150
194
  You can also retrieve split data.
151
195
 
152
196
  ```ruby
153
- data = YahooFinance.splits('AAPL', :start_date => Date.today - 10*365)
197
+ yahoo_client = YahooFinance::Client.new
198
+ data = yahoo_client.splits('AAPL', :start_date => Date.today - 10*365)
154
199
  data[0].date # Date<2014-06-09>
155
200
  data[0].before # 1
156
201
  data[0].after # 7
@@ -160,3 +205,4 @@ data[0].after # 7
160
205
  Enjoy! :-)
161
206
 
162
207
  - Herval (hervalfreire@gmail.com)
208
+ - Eric D. Santos Sosa (eric.santos@cometa.works)
@@ -0,0 +1,29 @@
1
+ # YahooFinance Module for YahooFinance gem
2
+ module YahooFinance
3
+ # FinanceUtils Module
4
+ module FinanceUtils
5
+ def self.included(base)
6
+ base.extend(self)
7
+ end
8
+
9
+ MARKETS = OpenStruct.new(
10
+ us: OpenStruct.new(
11
+ nasdaq: OpenStruct.new(
12
+ url: "http://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nasdaq&render=download"),
13
+ nyse: OpenStruct.new(
14
+ url: "http://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=nyse&render=download"),
15
+ amex: OpenStruct.new(
16
+ url: "http://www.nasdaq.com/screening/companies-by-name.aspx?letter=0&exchange=amex&render=download")))
17
+
18
+ def symbols_by_market(country, market)
19
+ symbols = []
20
+ market = MARKETS.send(country).send(market)
21
+ return symbols if market.nil?
22
+ CSV.foreach(open(market.url)) do |row|
23
+ next if row.first == "Symbol"
24
+ symbols.push(row.first.gsub(" ", ""))
25
+ end
26
+ symbols
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,4 @@
1
+ # Version Variable for Yahoo Finance Gem
2
+ module YahooFinance
3
+ VERSION = '1.2.1'
4
+ end
data/lib/yahoo-finance.rb CHANGED
@@ -1 +1,245 @@
1
- require 'yahoo_finance'
1
+ require "open-uri"
2
+ require "ostruct"
3
+ require "json"
4
+ require "yahoo-finance/version"
5
+ require "yahoo-finance/finance-utils"
6
+ require "csv"
7
+ require 'bigdecimal'
8
+
9
+ module YahooFinance
10
+ # Client for Yahoo Finance Queries
11
+ class Client
12
+ include YahooFinance::FinanceUtils
13
+
14
+ COLUMNS = {
15
+ :ask => ["a", BigDecimal],
16
+ :average_daily_volume => ["a2", BigDecimal],
17
+ :ask_size => ["a5", BigDecimal],
18
+ :bid => ["b", BigDecimal],
19
+ :ask_real_time => ["b2", Time],
20
+ :bid_real_time => ["b3", BigDecimal],
21
+ :book_value => ["b4", BigDecimal],
22
+ :bid_size => ["b6", BigDecimal],
23
+ :chance_and_percent_change => ["c", String],
24
+ :change => ["c1", BigDecimal],
25
+ :comission => ["c3", String],
26
+ :change_real_time => ["c6", BigDecimal],
27
+ :after_hours_change_real_time => ["c8", String],
28
+ :dividend_per_share => ["d", BigDecimal],
29
+ :last_trade_date => ["d1", DateTime],
30
+ :trade_date => ["d2", String],
31
+ :earnings_per_share => ["e", BigDecimal],
32
+ :error_indicator => ["e1", String],
33
+ :eps_estimate_current_year => ["e7", BigDecimal],
34
+ :eps_estimate_next_year => ["e8", BigDecimal],
35
+ :eps_estimate_next_quarter => ["e9", BigDecimal],
36
+ :float_shares => ["f6", BigDecimal],
37
+ :low => ["g", BigDecimal],
38
+ :high => ["h", BigDecimal],
39
+ :low_52_weeks => ["j", BigDecimal],
40
+ :high_52_weeks => ["k", BigDecimal],
41
+ :holdings_gain_percent => ["g1", BigDecimal],
42
+ :annualized_gain => ["g3", BigDecimal],
43
+ :holdings_gain => ["g4", BigDecimal],
44
+ :holdings_gain_percent_realtime => ["g5", BigDecimal],
45
+ :holdings_gain_realtime => ["g6", BigDecimal],
46
+ :more_info => ["i", String],
47
+ :order_book => ["i5", BigDecimal],
48
+ :market_capitalization => ["j1", BigDecimal],
49
+ :shares_outstanding => ["j2", BigDecimal],
50
+ :market_cap_realtime => ["j3", BigDecimal],
51
+ :ebitda => ["j4", BigDecimal],
52
+ :change_From_52_week_low => ["j5", BigDecimal],
53
+ :percent_change_from_52_week_low => ["j6", BigDecimal],
54
+ :last_trade_realtime_withtime => ["k1", String],
55
+ :change_percent_realtime => ["k2", String],
56
+ :last_trade_size => ["k3", BigDecimal],
57
+ :change_from_52_week_high => ["k4", BigDecimal],
58
+ :percent_change_from_52_week_high => ["k5", BigDecimal],
59
+ :last_trade_with_time => ["l", String],
60
+ :last_trade_price => ["l1", BigDecimal],
61
+ :close => ["l1", BigDecimal], # same as :last_trade_price
62
+ :high_limit => ["l2", BigDecimal],
63
+ :low_limit => ["l3", BigDecimal],
64
+ :days_range => ["m", BigDecimal],
65
+ :days_range_realtime => ["m2", BigDecimal],
66
+ :moving_average_50_day => ["m3", BigDecimal],
67
+ :moving_average_200_day => ["m4", BigDecimal],
68
+ :change_from_200_day_moving_average => ["m5", BigDecimal],
69
+ :percent_change_from_200_day_moving_average => ["m6", BigDecimal],
70
+ :change_from_50_day_moving_average => ["m7", BigDecimal],
71
+ :percent_change_from_50_day_moving_average => ["m8", BigDecimal],
72
+ :name => ["n", String],
73
+ :notes => ["n4", String],
74
+ :open => ["o", BigDecimal],
75
+ :previous_close => ["p", BigDecimal],
76
+ :price_paid => ["p1", BigDecimal],
77
+ :change_in_percent => ["p2", BigDecimal],
78
+ :price_per_sales => ["p5", BigDecimal],
79
+ :price_per_book => ["p6", BigDecimal],
80
+ :ex_dividend_date => ["q", DateTime],
81
+ :pe_ratio => ["p5", BigDecimal],
82
+ :dividend_pay_date => ["r1", String],
83
+ :pe_ratio_realtime => ["r2", BigDecimal],
84
+ :peg_ratio => ["r5", BigDecimal],
85
+ :price_eps_estimate_current_year => ["r6", BigDecimal],
86
+ :price_eps_Estimate_next_year => ["r7", BigDecimal],
87
+ :symbol => ["s", String],
88
+ :shares_owned => ["s1", BigDecimal],
89
+ :revenue => ["s6", BigDecimal],
90
+ :short_ratio => ["s7", BigDecimal],
91
+ :last_trade_time => ["t1", Time],
92
+ :trade_links => ["t6", String],
93
+ :ticker_trend => ["t7", String],
94
+ :one_year_target_price => ["t8", BigDecimal],
95
+ :volume => ["v", BigDecimal],
96
+ :holdings_value => ["v1", String],
97
+ :holdings_value_realtime => ["v7", String],
98
+ :weeks_range_52 => ["w", BigDecimal],
99
+ :day_value_change => ["w1", BigDecimal],
100
+ :day_value_change_realtime => ["w4", String],
101
+ :stock_exchange => ["x", String],
102
+ :dividend_yield => ["y", BigDecimal],
103
+ :adjusted_close => [nil, BigDecimal] # this one only comes in historical quotes
104
+ }
105
+
106
+ HISTORICAL_MODES = {
107
+ daily: "d",
108
+ weekly: "w",
109
+ monthly: "m",
110
+ dividends_only: "v"
111
+ }
112
+
113
+ SYMBOLS_PER_REQUEST = 50
114
+
115
+ # retrieve the quote data (an OpenStruct per quote)
116
+ # the options param can be used to specify the following attributes:
117
+ # :raw - if true, each column will be converted (to numbers, dates, etc)
118
+ def quotes(symbols_array, columns_array = [:symbol, :last_trade_price, :last_trade_date, :change, :previous_close], options = {})
119
+ # remove invalid keys
120
+ columns_array.reject! { |c| !COLUMNS.key?(c) }
121
+ columns_array << :symbol if columns_array.index(:symbol).nil?
122
+
123
+ # "N/A" is never present if { raw = false }
124
+ options[:na_as_nil] = true if options[:raw] == false
125
+
126
+ ret = []
127
+ symbols_array.each_slice(SYMBOLS_PER_REQUEST) do |symbols|
128
+ read_quotes(symbols.join("+"), columns_array).map do |row|
129
+ data = row.to_hash
130
+ if options[:na_as_nil]
131
+ data.each { |key, value| data[key] = nil if value == 'N/A' }
132
+ end
133
+ if options[:raw] == false
134
+ data.each { |key, value| data[key] = format(value, COLUMNS[key][1]) }
135
+ end
136
+ ret << OpenStruct.new(data)
137
+ end
138
+ end
139
+ ret
140
+ end
141
+
142
+ def quote(symbol, columns_array = [:symbol, :last_trade_price, :last_trade_date, :change, :previous_close], options = {})
143
+ options[:raw] ||= true
144
+ quotes([symbol], columns_array, options).first
145
+ end
146
+
147
+ def historical_quotes(symbol, options = {})
148
+ options[:raw] ||= true
149
+ options[:period] ||= :daily
150
+ read_historical(symbol, options).map do |row|
151
+ OpenStruct.new(row.to_hash.merge(symbol: symbol))
152
+ end
153
+ end
154
+
155
+ def symbols(query)
156
+ ret = []
157
+ read_symbols(query).each do |row|
158
+ ret << OpenStruct.new(row)
159
+ end
160
+ ret
161
+ end
162
+
163
+ def splits(symbol, options = {})
164
+ rows = read_splits(symbol, options).select { |row| row[0] == "SPLIT" }
165
+ rows.map do |type, date, value|
166
+ after, before = value.split(":")
167
+ OpenStruct.new(symbol: symbol, date: Date.strptime(date.strip, "%Y%m%d"), before: before.to_i, after: after.to_i)
168
+ end
169
+ end
170
+
171
+ def format(str, type)
172
+ if str.nil?
173
+ str
174
+ elsif type == BigDecimal
175
+ BigDecimal.new(str)
176
+ elsif type == DateTime
177
+ DateTime.parse(str)
178
+ elsif type == Time
179
+ Time.parse(str)
180
+ else
181
+ str
182
+ end
183
+ end
184
+
185
+ private
186
+
187
+ def read_quotes(symb_str, cols)
188
+ columns = "#{cols.map { |col| COLUMNS[col][0] }.join("")}"
189
+ conn = open("https://download.finance.yahoo.com/d/quotes.csv?s=#{URI.escape(symb_str)}&f=#{columns}")
190
+ CSV.parse(conn.read, headers: cols)
191
+ end
192
+
193
+ def read_historical(symbol, options)
194
+ params = { s: URI.escape(symbol), g: HISTORICAL_MODES[options[:period]], ignore: ".csv" }
195
+ if options[:start_date]
196
+ params[:a] = options[:start_date].month-1
197
+ params[:b] = options[:start_date].day
198
+ params[:c] = options[:start_date].year
199
+ end
200
+ if options[:end_date]
201
+ params[:d] = options[:end_date].month-1
202
+ params[:e] = options[:end_date].day
203
+ params[:f] = options[:end_date].year
204
+ end
205
+
206
+ url = "https://ichart.finance.yahoo.com/table.csv?#{params.map{|k, v| "#{k}=#{v}"}.join("&")}"
207
+ conn = open(url)
208
+ cols = if options[:period] == :dividends_only
209
+ [:dividend_pay_date, :dividend_yield]
210
+ else
211
+ [:trade_date, :open, :high, :low, :close, :volume, :adjusted_close]
212
+ end
213
+ result = CSV.parse(conn.read, headers: cols)
214
+ #:first_row, :header_converters => :symbol)
215
+ result.delete(0) # drop returned header
216
+ result
217
+ end
218
+
219
+ def read_splits(symbol, options)
220
+ params = { s: URI.escape(symbol), g: "v" }
221
+ if options[:start_date]
222
+ params[:a] = options[:start_date].month-1
223
+ params[:b] = options[:start_date].day
224
+ params[:c] = options[:start_date].year
225
+ end
226
+ if options[:end_date]
227
+ params[:d] = options[:end_date].month-1
228
+ params[:e] = options[:end_date].day
229
+ params[:f] = options[:end_date].year
230
+ end
231
+
232
+ url = "https://ichart.finance.yahoo.com/x?#{params.map{|k, v| "#{k}=#{v}"}.join("&")}"
233
+ conn = open(url)
234
+ CSV.parse(conn.read)
235
+ end
236
+
237
+ def read_symbols(query)
238
+ conn = open("http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=#{query}&region=US&lang=en-US&callback=YAHOO.Finance.SymbolSuggest.ssCallback")
239
+ result = conn.read
240
+ result.sub!("YAHOO.Finance.SymbolSuggest.ssCallback(", "").chomp!(");")
241
+ json_result = JSON.parse(result)
242
+ json_result["ResultSet"]["Result"]
243
+ end
244
+ end
245
+ end
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yahoo-finance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 1.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Herval Freire
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-24 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2017-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ! '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
13
69
  description:
14
70
  email: herval@hervalicio.us
15
71
  executables: []
@@ -21,7 +77,8 @@ files:
21
77
  - HISTORY
22
78
  - README.md
23
79
  - lib/yahoo-finance.rb
24
- - lib/yahoo_finance.rb
80
+ - lib/yahoo-finance/finance-utils.rb
81
+ - lib/yahoo-finance/version.rb
25
82
  homepage: http://hervalicio.us/blog
26
83
  licenses: []
27
84
  metadata: {}
@@ -31,17 +88,17 @@ require_paths:
31
88
  - lib
32
89
  required_ruby_version: !ruby/object:Gem::Requirement
33
90
  requirements:
34
- - - ">="
91
+ - - ! '>='
35
92
  - !ruby/object:Gem::Version
36
93
  version: '0'
37
94
  required_rubygems_version: !ruby/object:Gem::Requirement
38
95
  requirements:
39
- - - ">="
96
+ - - ! '>='
40
97
  - !ruby/object:Gem::Version
41
98
  version: '0'
42
99
  requirements: []
43
100
  rubyforge_project:
44
- rubygems_version: 2.2.2
101
+ rubygems_version: 2.4.8
45
102
  signing_key:
46
103
  specification_version: 4
47
104
  summary: A wrapper to Yahoo! Finance market data (quotes and exchange rates) feed
data/lib/yahoo_finance.rb DELETED
@@ -1,231 +0,0 @@
1
- require 'open-uri'
2
- require 'ostruct'
3
- require 'json'
4
-
5
- if RUBY_VERSION >= "1.9"
6
- require 'csv'
7
- else
8
- require 'rubygems'
9
- require 'fastercsv'
10
- class Object
11
- CSV = FCSV
12
- alias_method :CSV, :FCSV
13
- end
14
- end
15
-
16
- class YahooFinance
17
-
18
- VERSION = '0.2.0'
19
-
20
- COLUMNS = {
21
- :ask => "a",
22
- :average_daily_volume => "a2",
23
- :ask_size => "a5",
24
- :bid => "b",
25
- :ask_real_time => "b2",
26
- :bid_real_time => "b3",
27
- :book_value => "b4",
28
- :bid_size => "b6",
29
- :change_and_percent_change => "c",
30
- :change => "c1",
31
- :comission => "c3",
32
- :change_real_time => "c6",
33
- :after_hours_change_real_time => "c8",
34
- :dividend_per_share => "d",
35
- :last_trade_date => "d1",
36
- :trade_date => "d2",
37
- :earnings_per_share => "e",
38
- :error_indicator => "e1",
39
- :eps_estimate_current_year => "e7",
40
- :eps_estimate_next_year => "e8",
41
- :eps_estimate_next_quarter => "e9",
42
- :float_shares => "f6",
43
- :low => "g",
44
- :high => "h",
45
- :low_52_weeks => "j",
46
- :high_52_weeks => "k",
47
- :holdings_gain_percent => "g1",
48
- :annualized_gain => "g3",
49
- :holdings_gain => "g4",
50
- :holdings_gain_percent_realtime => "g5",
51
- :holdings_gain_realtime => "g6",
52
- :more_info => "i",
53
- :order_book => "i5",
54
- :market_capitalization => "j1",
55
- :market_cap_realtime => "j3",
56
- :ebitda => "j4",
57
- :change_From_52_week_low => "j5",
58
- :percent_change_from_52_week_low => "j6",
59
- :last_trade_realtime_withtime => "k1",
60
- :change_percent_realtime => "k2",
61
- :last_trade_size => "k3",
62
- :change_from_52_week_high => "k4",
63
- :percent_change_from_52_week_high => "k5",
64
- :last_trade_with_time => "l",
65
- :last_trade_price => "l1",
66
- :close => "l1",
67
- :high_limit => "l2",
68
- :low_limit => "l3",
69
- :days_range => "m",
70
- :days_range_realtime => "m2",
71
- :moving_average_50_day => "m3",
72
- :moving_average_200_day => "m4",
73
- :change_from_200_day_moving_average => "m5",
74
- :percent_change_from_200_day_moving_average => "m6",
75
- :change_from_50_day_moving_average => "m7",
76
- :percent_change_from_50_day_moving_average => "m8",
77
- :name => "n",
78
- :notes => "n4",
79
- :open => "o",
80
- :previous_close => "p",
81
- :price_paid => "p1",
82
- :change_in_percent => "p2",
83
- :price_per_sales => "p5",
84
- :price_per_book => "p6",
85
- :ex_dividend_date => "q",
86
- :pe_ratio => "r",
87
- :dividend_pay_date => "r1",
88
- :pe_ratio_realtime => "r2",
89
- :peg_ratio => "r5",
90
- :price_eps_estimate_current_year => "r6",
91
- :price_eps_Estimate_next_year => "r7",
92
- :symbol => "s",
93
- :shares_owned => "s1",
94
- :short_ratio => "s7",
95
- :last_trade_time => "t1",
96
- :trade_links => "t6",
97
- :ticker_trend => "t7",
98
- :one_year_target_price => "t8",
99
- :volume => "v",
100
- :holdings_value => "v1",
101
- :holdings_value_realtime => "v7",
102
- :weeks_range_52 => "w",
103
- :day_value_change => "w1",
104
- :day_value_change_realtime => "w4",
105
- :stock_exchange => "x",
106
- :dividend_yield => "y",
107
- :adjusted_close => nil # this one only comes in historical quotes
108
- }
109
-
110
- HISTORICAL_MODES = {
111
- :daily => "d",
112
- :weekly => "w",
113
- :monthly => "m",
114
- :dividends_only => "v"
115
- }
116
-
117
- SYMBOLS_PER_REQUEST = 50
118
-
119
- # retrieve the quote data (an OpenStruct per quote)
120
- # the options param can be used to specify the following attributes:
121
- # :raw - if true, each column will be converted (to numbers, dates, etc)
122
- def self.quotes(symbols_array, columns_array = [:symbol, :last_trade_price, :last_trade_date, :change, :previous_close], options = { })
123
- options[:raw] ||= true
124
-
125
- ret = []
126
- symbols_array.each_slice(SYMBOLS_PER_REQUEST) do |symbols|
127
- read_quotes(symbols.join("+"), columns_array).map do |row|
128
- ret << OpenStruct.new(row.to_hash)
129
- end
130
- end
131
- ret
132
- end
133
-
134
- def self.quote(symbol, columns_array = [:symbol, :last_trade_price, :last_trade_date, :change, :previous_close], options = { })
135
- options[:raw] ||= true
136
- quotes([symbol], columns_array, options).first
137
- end
138
-
139
- def self.historical_quotes(symbol, options = {})
140
- options[:raw] ||= true
141
- options[:period] ||= :daily
142
- read_historical(symbol, options).map do |row|
143
- OpenStruct.new(row.to_hash.merge(:symbol => symbol))
144
- end
145
- end
146
-
147
- def self.symbols(query)
148
- ret = []
149
- read_symbols(query).each do |row|
150
- ret << OpenStruct.new(row)
151
- end
152
- ret
153
- end
154
-
155
- def self.splits(symbol, options = {})
156
- rows = read_splits(symbol, options).select{|row| row[0] == 'SPLIT'}
157
- rows.map do |row|
158
- type, date, value = row
159
- after, before = value.split(':')
160
- OpenStruct.new(:symbol => symbol, :date => Date.strptime(date.strip, '%Y%m%d'), :before => before.to_i, :after => after.to_i)
161
- end
162
- end
163
-
164
- private
165
-
166
- def self.read_quotes(symb_str, cols)
167
- columns = "#{cols.map {|col| COLUMNS[col] }.join('')}"
168
- conn = open("http://download.finance.yahoo.com/d/quotes.csv?s=#{URI.escape(symb_str)}&f=#{columns}")
169
- CSV.parse(conn.read, :headers => cols)
170
- end
171
-
172
- def self.read_historical(symbol, options)
173
- params = {
174
- :s => URI.escape(symbol),
175
- :g => HISTORICAL_MODES[options[:period]],
176
- :ignore => '.csv',
177
- }
178
- if options[:start_date]
179
- params[:a] = options[:start_date].month-1
180
- params[:b] = options[:start_date].day
181
- params[:c] = options[:start_date].year
182
- end
183
- if options[:end_date]
184
- params[:d] = options[:end_date].month-1
185
- params[:e] = options[:end_date].day
186
- params[:f] = options[:end_date].year
187
- end
188
-
189
- url = "http://ichart.finance.yahoo.com/table.csv?#{params.map{|k, v| "#{k}=#{v}"}.join('&')}"
190
- conn = open(url)
191
- cols =
192
- if options[:period] == :dividends_only
193
- [:dividend_pay_date, :dividend_yield]
194
- else
195
- [:trade_date, :open, :high, :low, :close, :volume, :adjusted_close]
196
- end
197
- result = CSV.parse(conn.read, :headers => cols) #:first_row, :header_converters => :symbol)
198
- result.delete(0) # drop returned header
199
- result
200
- end
201
-
202
- def self.read_splits(symbol, options)
203
- params = {
204
- :s => URI.escape(symbol),
205
- :g => 'v'
206
- }
207
- if options[:start_date]
208
- params[:a] = options[:start_date].month-1
209
- params[:b] = options[:start_date].day
210
- params[:c] = options[:start_date].year
211
- end
212
- if options[:end_date]
213
- params[:d] = options[:end_date].month-1
214
- params[:e] = options[:end_date].day
215
- params[:f] = options[:end_date].year
216
- end
217
-
218
- url = "http://ichart.finance.yahoo.com/x?#{params.map{|k, v| "#{k}=#{v}"}.join('&')}"
219
- conn = open(url)
220
- CSV.parse(conn.read)
221
- end
222
-
223
- def self.read_symbols(query)
224
- conn = open("http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=#{query}&callback=YAHOO.Finance.SymbolSuggest.ssCallback")
225
- result = conn.read
226
- result.sub!('YAHOO.Finance.SymbolSuggest.ssCallback(', '').chomp!(')')
227
- json_result = JSON.parse(result)
228
- json_result["ResultSet"]["Result"]
229
- end
230
-
231
- end