market_beat 0.1.1 → 0.2.0
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.
- data/CHANGELOG +3 -0
- data/Gemfile.lock +1 -1
- data/LICENSE +1 -1
- data/README.md +11 -1
- data/lib/market_beat.rb +18 -7
- data/lib/market_beat/google.rb +1 -1
- data/lib/market_beat/google.yml +1 -1
- data/lib/market_beat/historical.rb +56 -0
- data/lib/market_beat/version.rb +2 -2
- data/lib/market_beat/yahoo.rb +1 -1
- data/lib/market_beat/yahoo.yml +1 -1
- data/spec/google_spec.rb +1 -1
- data/spec/historical_spec.rb +65 -0
- data/spec/market_beat_spec.rb +13 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/yahoo_spec.rb +1 -1
- metadata +38 -29
data/CHANGELOG
CHANGED
data/Gemfile.lock
CHANGED
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -31,6 +31,15 @@ Some methods return multiple values:
|
|
31
31
|
>> MarketBeat.last_trade_with_time :IBM
|
32
32
|
["4:02pm", "181.47"]
|
33
33
|
|
34
|
+
Fetching historical quotes returns array of hashes where each hash represents
|
35
|
+
stock data for a given date:
|
36
|
+
|
37
|
+
>> MarketBeat.quotes(:AAPL, "2011-12-21", "2011-12-22")
|
38
|
+
[{:date=>#<Date: 2011-12-22 (4911835/2,0,2299161)>, :open=>"397.00",
|
39
|
+
:high=>"399.13", :low=>"396.10", :close=>"398.55", :volume=>"7227016"},
|
40
|
+
{:date=>#<Date: 2011-12-21 (4911833/2,0,2299161)>, :open=>"396.69",
|
41
|
+
:high=>"397.30", :low=>"392.01", :close=>"396.44", :volume=>"9390954"}]
|
42
|
+
|
34
43
|
### Available Methods (Real Time Data) ###
|
35
44
|
|
36
45
|
MarketBeat.after_hours_change_real_time
|
@@ -133,6 +142,7 @@ Some methods return multiple values:
|
|
133
142
|
MarketBeat.price_to_eps_estimate_current_year
|
134
143
|
MarketBeat.price_to_eps_estimate_next_year
|
135
144
|
MarketBeat.price_to_sales
|
145
|
+
MarketBeat.quotes
|
136
146
|
MarketBeat.range_52_week
|
137
147
|
MarketBeat.shares_owned
|
138
148
|
MarketBeat.short_ratio
|
@@ -164,7 +174,7 @@ Some methods return multiple values:
|
|
164
174
|
* Send me a pull request.
|
165
175
|
|
166
176
|
### License ###
|
167
|
-
Copyright (c) 2011 Michael Dvorkin
|
177
|
+
Copyright (c) 2011-12 Michael Dvorkin
|
168
178
|
|
169
179
|
twitter.com/mid
|
170
180
|
|
data/lib/market_beat.rb
CHANGED
@@ -1,31 +1,42 @@
|
|
1
|
-
# Copyright (c) 2011 Michael Dvorkin
|
1
|
+
# Copyright (c) 2011-12 Michael Dvorkin
|
2
2
|
#
|
3
3
|
# Market Beat is freely distributable under the terms of MIT license.
|
4
4
|
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
5
|
#------------------------------------------------------------------------------
|
6
6
|
require File.dirname(__FILE__) + '/market_beat/yahoo'
|
7
7
|
require File.dirname(__FILE__) + '/market_beat/google'
|
8
|
+
require File.dirname(__FILE__) + '/market_beat/historical'
|
8
9
|
require File.dirname(__FILE__) + "/market_beat/version"
|
9
10
|
|
10
11
|
module MarketBeat
|
11
12
|
# Pre-cache available methods so we could use them within
|
12
13
|
# method_missing where respond_to? gives false positives.
|
14
|
+
@@methods = { :historical => [ :quotes ] }
|
13
15
|
if RUBY_VERSION < '1.9.0'
|
14
|
-
@@yahoo = (Yahoo.methods - Object.methods).map { |m| m.to_sym }
|
15
|
-
@@google = (Google.methods - Object.methods).map { |m| m.to_sym }
|
16
|
+
@@methods[:yahoo] = (Yahoo.methods - Object.methods).map { |m| m.to_sym }
|
17
|
+
@@methods[:google] = (Google.methods - Object.methods).map { |m| m.to_sym }
|
16
18
|
else
|
17
|
-
@@yahoo = Yahoo.methods - Object.methods
|
18
|
-
@@google = Google.methods - Object.methods
|
19
|
+
@@methods[:yahoo] = Yahoo.methods - Object.methods
|
20
|
+
@@methods[:google] = Google.methods - Object.methods
|
19
21
|
end
|
20
22
|
|
21
23
|
# Proxy MarketBeat methods to either Google or Yahoo providers.
|
22
24
|
def self.method_missing(method, *args, &blk)
|
23
|
-
if @@google.include?(method)
|
25
|
+
if @@methods[:google].include?(method)
|
24
26
|
Google.send(method, *args)
|
25
|
-
elsif @@yahoo.include?(method)
|
27
|
+
elsif @@methods[:yahoo].include?(method)
|
26
28
|
Yahoo.send(method, *args)
|
29
|
+
elsif @@methods[:historical].include?(method)
|
30
|
+
Historical.send(method, *args)
|
27
31
|
else
|
28
32
|
super
|
29
33
|
end
|
30
34
|
end
|
35
|
+
|
36
|
+
if RUBY_VERSION > '1.9'
|
37
|
+
# Make MarketBeat.respond_to? return true for all the methods above.
|
38
|
+
def self.respond_to_missing?(method, include_private)
|
39
|
+
super(method, include_private) || @@methods.values.flatten.include?(method)
|
40
|
+
end
|
41
|
+
end
|
31
42
|
end
|
data/lib/market_beat/google.rb
CHANGED
data/lib/market_beat/google.yml
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Copyright (c) 2011-12 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Market Beat is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
require "csv"
|
7
|
+
require "date"
|
8
|
+
|
9
|
+
module MarketBeat
|
10
|
+
class Historical
|
11
|
+
URL = "http://www.google.com/finance/historical?q=%s&startdate=%s&enddate=%s&output=csv"
|
12
|
+
|
13
|
+
class << self
|
14
|
+
private
|
15
|
+
#
|
16
|
+
# Fetch historical quotes. Return nil on error or an array of hashes
|
17
|
+
# representing stock data. Empty array means no data is available.
|
18
|
+
# Start and end date parameters should be either YYYY-MM-DD strings
|
19
|
+
# or Date objects.
|
20
|
+
#
|
21
|
+
def quotes(ticker, start_date, end_date = Date.today)
|
22
|
+
csv = fetch(ticker, start_date, end_date)
|
23
|
+
return nil unless csv
|
24
|
+
|
25
|
+
quotes = CSV.parse(csv) # Parse comma-delimited data.
|
26
|
+
quotes[1..-1].map do |col| # Skip header line.
|
27
|
+
#
|
28
|
+
# I guess Google finance folks are tight on data so they return year
|
29
|
+
# as two digits, ex: 23-Dec-11 or Apr-26-99. With the tweak below we
|
30
|
+
# should be good till year 2042 ;-)
|
31
|
+
#
|
32
|
+
date = *col[0].split("-")
|
33
|
+
date[2] = ((date[2] <= "42" ? "20" : "19") + date[2]) if date[2].size == 2
|
34
|
+
{ :date => Date.parse(date.join("-")),
|
35
|
+
:open => col[1],
|
36
|
+
:high => col[2],
|
37
|
+
:low => col[3],
|
38
|
+
:close => col[4],
|
39
|
+
:volume => col[5]
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
#
|
44
|
+
# Format the URL and fetch stock data.
|
45
|
+
#
|
46
|
+
def fetch(ticker, start_date, end_date)
|
47
|
+
uri = URI.parse(URL % [ ticker, start_date.to_s, end_date.to_s ])
|
48
|
+
response = Net::HTTP.get_response(uri)
|
49
|
+
response.body
|
50
|
+
rescue Exception => e
|
51
|
+
$stderr.puts "market_beat: error fetching quotes\n#{e.inspect}"
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/market_beat/version.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
# Copyright (c) 2011 Michael Dvorkin
|
1
|
+
# Copyright (c) 2011-12 Michael Dvorkin
|
2
2
|
#
|
3
3
|
# Market Beat is freely distributable under the terms of MIT license.
|
4
4
|
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
5
|
#------------------------------------------------------------------------------
|
6
6
|
module MarketBeat
|
7
7
|
def self.version
|
8
|
-
'0.
|
8
|
+
'0.2.0'
|
9
9
|
end
|
10
10
|
end
|
data/lib/market_beat/yahoo.rb
CHANGED
data/lib/market_beat/yahoo.yml
CHANGED
data/spec/google_spec.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Copyright (c) 2011-12 Michael Dvorkin
|
2
|
+
#
|
3
|
+
# Market Beat is freely distributable under the terms of MIT license.
|
4
|
+
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
5
|
+
#------------------------------------------------------------------------------
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
7
|
+
require "stringio"
|
8
|
+
require "date"
|
9
|
+
|
10
|
+
describe "MarketBeat::Historical" do
|
11
|
+
before(:all) do
|
12
|
+
@csv = File.read(File.dirname(__FILE__) + '/fixtures/AAPL.csv')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should return correct data when using strings as start/end dates" do
|
16
|
+
response = mock(:body => @csv)
|
17
|
+
Net::HTTP.should_receive(:get_response).once.and_return(response)
|
18
|
+
quotes = MarketBeat.quotes(:aapl, "2011-12-21", "2011-12-23")
|
19
|
+
quotes.size.should == 3
|
20
|
+
quotes[0].keys.map(&:to_s).sort.should == %w(close date high low open volume)
|
21
|
+
quotes[0][:open].should == "403.43"
|
22
|
+
quotes[0][:high].should == "403.43"
|
23
|
+
quotes[0][:low].should == "403.43"
|
24
|
+
quotes[0][:close].should == "403.43"
|
25
|
+
quotes[0][:volume].should == "0"
|
26
|
+
quotes[0][:date].to_s.should == "2011-12-23"
|
27
|
+
quotes[1][:date].to_s.should == "2011-12-22"
|
28
|
+
quotes[2][:date].to_s.should == "2011-12-21"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should return correct data when using Date as start/end dates" do
|
32
|
+
response = mock(:body => @csv)
|
33
|
+
Net::HTTP.should_receive(:get_response).once.and_return(response)
|
34
|
+
quotes = MarketBeat.quotes(:aapl, Date.parse("2011-12-21"), Date.parse("2011-12-23"))
|
35
|
+
quotes.size.should == 3
|
36
|
+
quotes[2].keys.map(&:to_s).sort.should == %w(close date high low open volume)
|
37
|
+
quotes[2][:open].should == "396.69"
|
38
|
+
quotes[2][:high].should == "397.30"
|
39
|
+
quotes[2][:low].should == "392.01"
|
40
|
+
quotes[2][:close].should == "396.44"
|
41
|
+
quotes[2][:volume].should == "9390954"
|
42
|
+
quotes[2][:date].to_s.should == "2011-12-21"
|
43
|
+
quotes[1][:date].to_s.should == "2011-12-22"
|
44
|
+
quotes[0][:date].to_s.should == "2011-12-23"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return empty array when no data is available" do
|
48
|
+
response = mock(:body => @csv.split.first) # Just the header row.
|
49
|
+
Net::HTTP.should_receive(:get_response).once.and_return(response)
|
50
|
+
MarketBeat.quotes(:aapl, "2011-12-21", "2011-12-23").should == []
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return nil on error" do
|
54
|
+
begin
|
55
|
+
stderr, $stderr = $stderr, StringIO.new
|
56
|
+
response = mock(:body => "")
|
57
|
+
Net::HTTP.should_receive(:get_response).once.and_raise(SocketError)
|
58
|
+
MarketBeat.quotes(:aapl, "2011-12-21", "2011-12-23").should == nil
|
59
|
+
$stderr.string.should =~ /^market_beat: error fetching quotes/m
|
60
|
+
ensure
|
61
|
+
$stderr = stderr
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
data/spec/market_beat_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2011 Michael Dvorkin
|
1
|
+
# Copyright (c) 2011-12 Michael Dvorkin
|
2
2
|
#
|
3
3
|
# Market Beat is freely distributable under the terms of MIT license.
|
4
4
|
# See LICENSE file or http://www.opensource.org/licenses/mit-license.php
|
@@ -9,6 +9,12 @@ require 'yaml'
|
|
9
9
|
describe "MarketBeat Google Proxy" do
|
10
10
|
metrics = YAML.load_file(File.dirname(__FILE__) + '/../lib/market_beat/google.yml')
|
11
11
|
metrics.values.each do |method|
|
12
|
+
if RUBY_VERSION > '1.9'
|
13
|
+
it "MarketBeat should respond to :#{method}" do
|
14
|
+
MarketBeat.respond_to?(method).should == true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
12
18
|
it "Google.#{method}" do
|
13
19
|
MarketBeat::Google.should_receive(method).once
|
14
20
|
MarketBeat::Yahoo.should_not_receive(method)
|
@@ -21,6 +27,12 @@ describe "MarketBeat Yahoo Proxy" do
|
|
21
27
|
yahoo_metrics = YAML.load_file(File.dirname(__FILE__) + '/../lib/market_beat/yahoo.yml')
|
22
28
|
google_metrics = YAML.load_file(File.dirname(__FILE__) + '/../lib/market_beat/google.yml')
|
23
29
|
yahoo_metrics.values.each do |method|
|
30
|
+
if RUBY_VERSION > '1.9'
|
31
|
+
it "MarketBeat should respond to :#{method}" do
|
32
|
+
MarketBeat.respond_to?(method).should == true
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
24
36
|
it "Yahoo.#{method}" do # If Yahoo and Google have the same method Google takes precedence.
|
25
37
|
if google_metrics.values.include?(method)
|
26
38
|
MarketBeat::Google.should_receive(method).once
|
data/spec/spec_helper.rb
CHANGED
data/spec/yahoo_spec.rb
CHANGED
metadata
CHANGED
@@ -1,34 +1,37 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: market_beat
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.1
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Michael Dvorkin
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
|
13
|
+
date: 2012-01-15 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
15
16
|
name: rspec
|
16
|
-
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
19
|
none: false
|
18
|
-
requirements:
|
19
|
-
- -
|
20
|
-
- !ruby/object:Gem::Version
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
21
23
|
version: 2.6.0
|
22
24
|
type: :development
|
23
|
-
|
24
|
-
|
25
|
-
description: Fetch real-time and delayed stock quotes and 100+ other financial and
|
26
|
-
market indicaors from publicly available sources.
|
25
|
+
version_requirements: *id001
|
26
|
+
description: Fetch real-time and delayed stock quotes and 100+ other financial and market indicaors from publicly available sources.
|
27
27
|
email: mike@dvorkin.net
|
28
28
|
executables: []
|
29
|
+
|
29
30
|
extensions: []
|
31
|
+
|
30
32
|
extra_rdoc_files: []
|
31
|
-
|
33
|
+
|
34
|
+
files:
|
32
35
|
- CHANGELOG
|
33
36
|
- Gemfile
|
34
37
|
- Gemfile.lock
|
@@ -36,42 +39,48 @@ files:
|
|
36
39
|
- Rakefile
|
37
40
|
- README.md
|
38
41
|
- lib/market_beat/google.rb
|
42
|
+
- lib/market_beat/historical.rb
|
39
43
|
- lib/market_beat/version.rb
|
40
44
|
- lib/market_beat/yahoo.rb
|
41
45
|
- lib/market_beat.rb
|
42
46
|
- lib/market_beat/google.yml
|
43
47
|
- lib/market_beat/yahoo.yml
|
44
48
|
- spec/google_spec.rb
|
49
|
+
- spec/historical_spec.rb
|
45
50
|
- spec/market_beat_spec.rb
|
46
51
|
- spec/spec_helper.rb
|
47
52
|
- spec/yahoo_spec.rb
|
48
53
|
- .gitignore
|
49
54
|
homepage: http://github.com/michaeldv/market_beat
|
50
55
|
licenses: []
|
56
|
+
|
51
57
|
post_install_message:
|
52
58
|
rdoc_options: []
|
53
|
-
|
59
|
+
|
60
|
+
require_paths:
|
54
61
|
- lib
|
55
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
63
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version:
|
61
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
69
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
version:
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
67
74
|
requirements: []
|
75
|
+
|
68
76
|
rubyforge_project: market_beat
|
69
|
-
rubygems_version: 1.8.
|
77
|
+
rubygems_version: 1.8.5
|
70
78
|
signing_key:
|
71
79
|
specification_version: 3
|
72
80
|
summary: Fetch up-to-date stock quotes and 100+ financial and market indicators.
|
73
|
-
test_files:
|
81
|
+
test_files:
|
74
82
|
- spec/google_spec.rb
|
83
|
+
- spec/historical_spec.rb
|
75
84
|
- spec/market_beat_spec.rb
|
76
85
|
- spec/spec_helper.rb
|
77
86
|
- spec/yahoo_spec.rb
|