yahoo-finance 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. data/HISTORY +8 -0
  2. data/README +32 -6
  3. data/lib/yahoo_finance.rb +199 -0
  4. metadata +6 -4
  5. data/bin/yahoo_finance.rb +0 -133
data/HISTORY ADDED
@@ -0,0 +1,8 @@
1
+ Version 0.0.2 - August 05, 2007
2
+ ===============================
3
+ * Type-casting: pass the option :raw => false to the quotes method to get columns converted from string to specific types (mostly float, date, time and datetime)
4
+ * Historical quotes: a convenient method to get historical quotes for a given symbol in an interval, getting either daily, weekly or monthly quotes - or dividend yields only
5
+
6
+ Version 0.0.1 - August 04, 2007
7
+ ===============================
8
+ * Initial implementation - no bells, no whristles :)
data/README CHANGED
@@ -3,13 +3,21 @@ Ruby's Yahoo Finance Wrapper
3
3
 
4
4
  A dead simple wrapper for yahoo finance quotes end-point.
5
5
 
6
-
7
6
  Usage:
7
+
8
+ 1 - Getting latest quotes for a set of symbols
9
+ ----------------------------------------------
8
10
  Just pass an array of symbols (stock names, indexes, exchange rates) and a list of fields you want:
9
11
 
10
- data = Yahoo::Finance.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date])
11
- puts data[0].symbol + " value is: " + data[0].ask
12
+ data = YahooFinance.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date])
13
+ # ask will be a string here:
14
+ puts data[0].symbol + " value is: " + data[0].ask
15
+
16
+ Or optionally:
12
17
 
18
+ data = YahooFinance.quotes(["BVSP", "NATU3.SA", "USDJPY=X"], [:ask, :bid, :last_trade_date], { :raw => false } )
19
+ # ask will be a float here:
20
+ puts data[0].symbol + " value is: " + data[0].ask
13
21
 
14
22
  The full list of fields follows:
15
23
 
@@ -35,8 +43,8 @@ The full list of fields follows:
35
43
  :eps_estimate_next_year
36
44
  :eps_estimate_next_quarter
37
45
  :float_shares
38
- :days_low
39
- :days_high
46
+ :low
47
+ :high
40
48
  :low_52_weeks
41
49
  :high_52_weeks
42
50
  :holdings_gain_percent
@@ -57,7 +65,8 @@ The full list of fields follows:
57
65
  :change_from_52_week_high
58
66
  :percent_change_from_52_week_high
59
67
  :last_trade_with_time
60
- :last_trade_price_only
68
+ :last_trade_price
69
+ :close
61
70
  :high_limit
62
71
  :low_limit
63
72
  :days_range
@@ -100,6 +109,23 @@ The full list of fields follows:
100
109
  :dividend_yield
101
110
 
102
111
 
112
+ 2 - Getting historical quotes
113
+ -----------------------------
114
+
115
+ Here you can specify a date range and a symbol, and retrieve historical data for it.
116
+ The last parameter (options) can include, besides the "raw" option, a "period" option.
117
+ The period can be specified as :daily, :monthly, :weekly or :dividends_only
118
+
119
+ data = YahooFinance.historical_quotes("BVSP", Time::now-(24*60*60*10), Time::now) # 10 days worth of data
120
+
121
+ or
122
+
123
+ data = YahooFinance.historical_quotes("BVSP", Time::now-(24*60*60*10), Time::now, { :raw => false, :period => :monthly })
124
+
125
+
126
+
127
+
128
+
103
129
  Enjoy! :-)
104
130
 
105
131
  - Herval (contact@hervalicio.us)
@@ -0,0 +1,199 @@
1
+ require 'open-uri'
2
+ require 'ostruct'
3
+
4
+ class YahooFinance
5
+
6
+ VERSION = '0.0.2'
7
+
8
+ COLUMNS = {
9
+ :ask => ["a", :float],
10
+ :average_daily_volume => ["a2", :float],
11
+ :ask_size => ["a5", :integer],
12
+ :bid => ["b", :float],
13
+ :ask_real_time => ["b2", :time],
14
+ :bid_real_time => ["b3", :float],
15
+ :book_value => ["b4", :float],
16
+ :bid_size => ["b6", :integer],
17
+ :chance_and_percent_change => ["c", :string],
18
+ :change => ["c1", :float],
19
+ :comission => ["c3", :undefined],
20
+ :change_real_time => ["c6", :float],
21
+ :after_hours_change_real_time => ["c8", :undefined],
22
+ :dividend_per_share => ["d", :float],
23
+ :last_trade_date => ["d1", :date],
24
+ :trade_date => ["d2", :undefined],
25
+ :earnings_per_share => ["e", :float],
26
+ :error_indicator => ["e1", :string],
27
+ :eps_estimate_current_year => ["e7", :float],
28
+ :eps_estimate_next_year => ["e8", :float],
29
+ :eps_estimate_next_quarter => ["e9", :float],
30
+ :float_shares => ["f6", :float],
31
+ :low => ["g", :float],
32
+ :high => ["h", :float],
33
+ :low_52_weeks => ["j", :float],
34
+ :high_52_weeks => ["k", :float],
35
+ :holdings_gain_percent => ["g1", :float],
36
+ :annualized_gain => ["g3", :float],
37
+ :holdings_gain => ["g4", :float],
38
+ :holdings_gain_percent_realtime => ["g5", :float],
39
+ :holdings_gain_realtime => ["g6", :float],
40
+ :more_info => ["i", :string],
41
+ :order_book => ["i5", :float],
42
+ :market_capitalization => ["j1", :currency_amount],
43
+ :market_cap_realtime => ["j3", :currency_amount],
44
+ :ebitda => ["j4", :currency_amount],
45
+ :change_From_52_week_low => ["j5", :float],
46
+ :percent_change_from_52_week_low => ["j6", :float],
47
+ :last_trade_realtime_withtime => ["k1", :string],
48
+ :change_percent_realtime => ["k2", :string],
49
+ :last_trade_size => ["k3", :integer],
50
+ :change_from_52_week_high => ["k4", :float],
51
+ :percent_change_from_52_week_high => ["k5", :float],
52
+ :last_trade_with_time => ["l", :string],
53
+ :last_trade_price => ["l1", :float],
54
+ :close => ["l1", :float], # same as :last_trade_price
55
+ :high_limit => ["l2", :float],
56
+ :low_limit => ["l3", :float],
57
+ :days_range => ["m", :float],
58
+ :days_range_realtime => ["m2", :float],
59
+ :moving_average_50_day => ["m3", :float],
60
+ :moving_average_200_day => ["m4", :float],
61
+ :change_from_200_day_moving_average => ["m5", :float],
62
+ :percent_change_from_200_day_moving_average => ["m6", :float],
63
+ :change_from_50_day_moving_average => ["m7", :float],
64
+ :percent_change_from_50_day_moving_average => ["m8", :float],
65
+ :name => ["n", :string],
66
+ :notes => ["n4", :string],
67
+ :open => ["o", :float],
68
+ :previous_close => ["p", :float],
69
+ :price_paid => ["p1", :float],
70
+ :change_in_percent => ["p2", :float],
71
+ :price_per_sales => ["p5", :float],
72
+ :price_per_book => ["p6", :float],
73
+ :ex_dividend_date => ["q", :date],
74
+ :pe_ratio => ["p5", :float],
75
+ :dividend_pay_date => ["r1", :undefined],
76
+ :pe_ratio_realtime => ["r2", :float],
77
+ :peg_ratio => ["r5", :float],
78
+ :price_eps_estimate_current_year => ["r6", :float],
79
+ :price_eps_Estimate_next_year => ["r7", :float],
80
+ :symbol => ["s", :string],
81
+ :shares_owned => ["s1", :float],
82
+ :short_ratio => ["s7", :float],
83
+ :last_trade_time => ["t1", :time],
84
+ :trade_links => ["t6", :string],
85
+ :ticker_trend => ["t7", :string],
86
+ :one_year_target_price => ["t8", :float],
87
+ :volume => ["v", :float],
88
+ :holdings_value => ["v1", :undefined],
89
+ :holdings_value_realtime => ["v7", :undefined],
90
+ :weeks_range_52 => ["w", :float],
91
+ :day_value_change => ["w1", :float],
92
+ :day_value_change_realtime => ["w4", :string],
93
+ :stock_exchange => ["x", :string],
94
+ :dividend_yield => ["y", :float],
95
+ :adjusted_close => [nil, :float] # this one only comes in historical quotes
96
+ }
97
+
98
+ HISTORICAL_MODES = {
99
+ :daily => "d",
100
+ :weekly => "w",
101
+ :monthly => "m",
102
+ :dividends_only => "v"
103
+ }
104
+
105
+ ROWS_PER_REQUEST = 50
106
+
107
+ # retrieve the quote data (an OpenStruct per quote)
108
+ # the options param can be used to specify the following attributes:
109
+ # :raw - if true, each column will be converted (to numbers, dates, etc)
110
+ def self.quotes(symbols_array, columns_array = [:symbol, :last_trade_price, :last_trade_date, :change, :previous_close], options = { :raw => true })
111
+ ret = []
112
+ cols = columns_array.collect { |c| COLUMNS[c][0] }.join
113
+ types = columns_array.collect { |c| COLUMNS[c][1] }.join if options[:raw]
114
+
115
+ i = 0
116
+ k = 0
117
+ while i < symbols_array.size
118
+ subset = symbols_array[i..i+ROWS_PER_REQUEST]
119
+ symb_str = subset.collect { |s| "#{s}" }.join("+")
120
+
121
+ lines = read_lines(symb_str, cols)
122
+ for line in lines
123
+ ret << extract_data(line, symbols_array[k], columns_array, options)
124
+ k+=1
125
+ end
126
+
127
+ i += ROWS_PER_REQUEST+1
128
+ end
129
+
130
+ return ret
131
+ end
132
+
133
+ def self.historical_quotes(symbol, start_date, end_date, options = { :raw => true, :period => :daily })
134
+ options[:period] ||= :daily
135
+ lines = read_historical(symbol, start_date, end_date, options)
136
+ ret = []
137
+
138
+ if options[:period] == :dividends_only
139
+ cols = [:dividend_pay_date, :dividend_yield]
140
+ else
141
+ cols = [:trade_date, :open, :high, :low, :close, :volume, :adjusted_close]
142
+ end
143
+
144
+ for line in lines
145
+ ret << extract_data(line, symbol, cols, options)
146
+ end
147
+
148
+ return ret
149
+ end
150
+
151
+ private
152
+
153
+ def self.extract_data(raw_line, symbol, columns_array, options)
154
+ datamap = {}
155
+ datamap[:symbol] = symbol
156
+ data = raw_line.split(',')
157
+
158
+ for j in (0..data.size-1)
159
+ if !options[:raw]
160
+ datamap[columns_array[j]] = format(data[j], COLUMNS[columns_array[j]][1])
161
+ else
162
+ datamap[columns_array[j]] = data[j]
163
+ end
164
+ end
165
+
166
+ OpenStruct.new(datamap)
167
+ end
168
+
169
+ def self.format(str, type)
170
+ case type
171
+ when :float then str.to_f
172
+ when :integer then str.to_i
173
+ #when :date then DateTime::parse(str)
174
+ #when :time then Time.parse(str)
175
+ else str
176
+ end
177
+ end
178
+
179
+ def self.read_lines(symb_str, cols)
180
+ conn = open("http://finance.yahoo.com/d/quotes.csv?s=#{symb_str}&f=#{cols}")
181
+ lines = conn.read
182
+
183
+ lines.split("\r\n")
184
+ end
185
+
186
+ def self.read_historical(symbol, start_date, end_date, options)
187
+ url = "http://ichart.finance.yahoo.com/table.csv?s=#{symbol}&d=#{end_date.month-1}&e=#{end_date.day}&f=#{end_date.year}&g=#{HISTORICAL_MODES[options[:period]]}&a=#{start_date.month-1}&b=#{start_date.day}&c=#{start_date.year}&ignore=.csv"
188
+ begin
189
+ conn = open(url)
190
+ rescue
191
+ return []
192
+ end
193
+ lines = conn.read
194
+
195
+ all_lines = lines.split("\n")
196
+ return all_lines[1..all_lines.size-1]
197
+ end
198
+
199
+ end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: yahoo-finance
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.1
7
- date: 2007-08-04 00:00:00 -03:00
6
+ version: 0.0.2
7
+ date: 2007-08-05 00:00:00 -03:00
8
8
  summary: A wrapper to Yahoo! Finance market data (quotes and exchange rates) feed
9
9
  require_paths:
10
10
  - lib
@@ -12,7 +12,7 @@ email: herval@hervalicio.us
12
12
  homepage: http://hervalicio.us/blog
13
13
  rubyforge_project:
14
14
  description:
15
- autorequire:
15
+ autorequire: yahoo_finance
16
16
  default_executable:
17
17
  bindir: bin
18
18
  has_rdoc: false
@@ -29,14 +29,16 @@ post_install_message:
29
29
  authors:
30
30
  - Herval Freire
31
31
  files:
32
- - bin/yahoo_finance.rb
32
+ - lib/yahoo_finance.rb
33
33
  - README
34
+ - HISTORY
34
35
  test_files: []
35
36
 
36
37
  rdoc_options: []
37
38
 
38
39
  extra_rdoc_files:
39
40
  - README
41
+ - HISTORY
40
42
  executables: []
41
43
 
42
44
  extensions: []
@@ -1,133 +0,0 @@
1
- require 'open-uri'
2
- require 'ostruct'
3
-
4
- module Yahoo
5
-
6
- class Finance
7
-
8
- VERSION = '0.0.1'
9
-
10
- @@columns = {
11
- :ask => "a",
12
- :average_daily_volume => "a2",
13
- :ask_size => "a5",
14
- :bid => "b",
15
- :ask_real_time => "b2",
16
- :bid_real_time => "b3",
17
- :book_value => "b4",
18
- :bid_size => "b6",
19
- :chance_and_percent_change => "c",
20
- :change => "c1",
21
- :comission => "c3",
22
- :change_real_time => "c6",
23
- :after_hours_change_real_time => "c8",
24
- :dividend_per_share => "d",
25
- :last_trade_date => "d1",
26
- :trade_date => "d2",
27
- :earnings_per_share => "e",
28
- :error_indicator => "e1",
29
- :eps_estimate_current_year => "e7",
30
- :eps_estimate_next_year => "e8",
31
- :eps_estimate_next_quarter => "e9",
32
- :float_shares => "f6",
33
- :days_low => "g",
34
- :days_high => "h",
35
- :low_52_weeks => "j",
36
- :high_52_weeks => "k",
37
- :holdings_gain_percent => "g1",
38
- :annualized_gain => "g3",
39
- :holdings_gain => "g4",
40
- :holdings_gain_percent_realtime => "g5",
41
- :holdings_gain_realtime => "g6",
42
- :more_info => "i",
43
- :order_book => "i5",
44
- :market_capitalization => "j1",
45
- :market_cap_realtime => "j3",
46
- :ebitda => "j4",
47
- :change_From_52_week_low => "j5",
48
- :percent_change_from_52_week_low => "j6",
49
- :last_trade_realtime_withtime => "k1",
50
- :change_percent_realtime => "k2",
51
- :last_trade_size => "k3",
52
- :change_from_52_week_high => "k4",
53
- :percent_change_from_52_week_high => "k5",
54
- :last_trade_with_time => "l",
55
- :last_trade_price_only => "l1",
56
- :high_limit => "l2",
57
- :low_limit => "l3",
58
- :days_range => "m",
59
- :days_range_realtime => "m2",
60
- :moving_average_50_day => "m3",
61
- :moving_average_200_day => "m4",
62
- :change_from_200_day_moving_average => "m5",
63
- :percent_change_from_200_day_moving_average => "m6",
64
- :change_from_50_day_moving_average => "m7",
65
- :percent_change_from_50_day_moving_average => "m8",
66
- :name => "n",
67
- :notes => "n4",
68
- :open => "o",
69
- :previous_close => "p",
70
- :price_paid => "p1",
71
- :change_in_percent => "p2",
72
- :price_per_sales => "p5",
73
- :price_per_book => "p6",
74
- :ex_dividend_date => "q",
75
- :pe_ratio => "p5",
76
- :dividend_pay_date => "r1",
77
- :pe_ratio_realtime => "r2",
78
- :peg_ratio => "r5",
79
- :price_eps_estimate_current_year => "r6",
80
- :price_eps_Estimate_next_year => "r7",
81
- :symbol => "s",
82
- :shares_owned => "s1",
83
- :short_ratio => "s7",
84
- :last_trade_time => "t1",
85
- :trade_links => "t6",
86
- :ticker_trend => "t7",
87
- :one_year_target_price => "t8",
88
- :volume => "v",
89
- :holdings_value => "v1",
90
- :holdings_value_realtime => "v7",
91
- :weeks_range_52 => "w",
92
- :day_value_change => "w1",
93
- :day_value_change_realtime => "w4",
94
- :stock_exchange => "x",
95
- :dividend_yield => "y"
96
- }
97
-
98
- ROWS_PER_REQUEST = 50
99
-
100
- def self.quotes(symbols_array, columns_array = [:symbol, :ask, :bid])
101
- ret = []
102
- cols = columns_array.collect { |c| @@columns[c] }.join
103
-
104
- i = 0
105
- k = 0
106
- while i < symbols_array.size
107
- subset = symbols_array[i..i+ROWS_PER_REQUEST]
108
- symb_str = subset.collect { |s| "#{s}" }.join("+")
109
-
110
- conn = open("http://finance.yahoo.com/d/quotes.csv?s=#{symb_str}&f=#{cols}")
111
- lines = conn.read.split
112
- for line in lines
113
- datamap = {}
114
- datamap[:symbol] = symbols_array[k]
115
- data = line.split(',')
116
-
117
- for j in (0..data.size-1)
118
- datamap[columns_array[j]] = data[j]
119
- end
120
-
121
- ret << OpenStruct.new(datamap)
122
- k+=1
123
- end
124
-
125
- i += ROWS_PER_REQUEST+1
126
- end
127
-
128
- return ret
129
-
130
- end
131
- end
132
-
133
- end