yahoo-finance 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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