ticker_fetcher 0.3.1 → 0.4.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/LICENSE +1 -1
- data/README.rdoc +12 -1
- data/lib/ticker_fetcher/retriever.rb +83 -0
- data/lib/ticker_fetcher/stock.rb +17 -0
- data/test/helper.rb +0 -1
- data/test/test_retriever.rb +78 -0
- data/test/test_stock.rb +25 -0
- data/ticker_fetcher.gemspec +1 -1
- metadata +8 -6
- data/lib/ticker_fetcher.rb +0 -80
- data/test/test_ticker_fetcher.rb +0 -77
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -1,6 +1,17 @@
|
|
1
1
|
= ticker_fetcher
|
2
2
|
|
3
|
-
|
3
|
+
Downloads basic company information for the three major US stock exchanges (NYSE, Nasdaq, Amex).
|
4
|
+
|
5
|
+
== Installation
|
6
|
+
|
7
|
+
gem install ticker_fetcher
|
8
|
+
|
9
|
+
== Usage
|
10
|
+
|
11
|
+
tf = TickerFetcher::Retriever.new
|
12
|
+
tf.run # gets all 3 exchanges
|
13
|
+
tf.run('NASD') # gets the specified exchange
|
14
|
+
tf['NASD']
|
4
15
|
|
5
16
|
== Note on Patches/Pull Requests
|
6
17
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'csv'
|
4
|
+
require 'ticker_fetcher/stock'
|
5
|
+
|
6
|
+
module TickerFetcher
|
7
|
+
class Retriever
|
8
|
+
Symbol = 0
|
9
|
+
Name = 1
|
10
|
+
LastSale = 2
|
11
|
+
MarketCap = 3
|
12
|
+
IPOYear = 4
|
13
|
+
Sector = 5
|
14
|
+
Industry = 6
|
15
|
+
attr_reader :exchanges, :exchange_urls
|
16
|
+
|
17
|
+
# Passing an exchange name will retrieve only that exchange. Default is to retrieve all.
|
18
|
+
def initialize
|
19
|
+
@exchanges = {}
|
20
|
+
@exchange_urls = {
|
21
|
+
'AMEX' => 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=AMEX&render=download',
|
22
|
+
'NASD' => 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NASDAQ&render=download',
|
23
|
+
'NYSE' => 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NYSE&render=download'
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def run(exchange=:all)
|
28
|
+
if exchange == :all
|
29
|
+
@exchange_urls.each { |exchange, url| @exchanges[exchange] = parse_exchange(exchange, url) }
|
30
|
+
else
|
31
|
+
@exchanges[exchange] = parse_exchange(exchange, @exchange_urls[exchange])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_exchange(exchange, url)
|
36
|
+
data = open(url)
|
37
|
+
parse_csv(data)
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](exchange)
|
41
|
+
exchanges[exchange]
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def parse_csv(data)
|
47
|
+
CSV.parse(data, :headers => true).inject([]) do |stocks, row|
|
48
|
+
stocks << TickerFetcher::Stock.new([ticker(row), name(row), last_sale(row), market_cap(row), ipo_year(row), sector(row), industry(row)])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def name(row)
|
53
|
+
row[Name]
|
54
|
+
end
|
55
|
+
|
56
|
+
def ticker(row)
|
57
|
+
ticker = row[Symbol].strip.gsub('"', '')
|
58
|
+
unless(ticker.nil? || ticker.empty?)
|
59
|
+
ticker = ticker =~ /\W/ ? ticker.gsub('/', '.').gsub('^', '-') : ticker
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def last_sale(row)
|
64
|
+
row[LastSale]
|
65
|
+
end
|
66
|
+
|
67
|
+
def market_cap(row)
|
68
|
+
row[MarketCap]
|
69
|
+
end
|
70
|
+
|
71
|
+
def ipo_year(row)
|
72
|
+
row[IPOYear]
|
73
|
+
end
|
74
|
+
|
75
|
+
def sector(row)
|
76
|
+
row[Sector]
|
77
|
+
end
|
78
|
+
|
79
|
+
def industry(row)
|
80
|
+
row[Industry]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'ticker_fetcher/retriever'
|
2
|
+
|
3
|
+
module TickerFetcher
|
4
|
+
class Stock
|
5
|
+
attr_reader :symbol, :name, :last_sale, :market_cap, :ipo_year, :sector, :industry
|
6
|
+
|
7
|
+
def initialize(data)
|
8
|
+
@symbol = data[TickerFetcher::Retriever::Symbol]
|
9
|
+
@name = data[TickerFetcher::Retriever::Name]
|
10
|
+
@last_sale = data[TickerFetcher::Retriever::LastSale]
|
11
|
+
@market_cap = data[TickerFetcher::Retriever::MarketCap]
|
12
|
+
@ipo_year = data[TickerFetcher::Retriever::IPOYear]
|
13
|
+
@sector = data[TickerFetcher::Retriever::Sector]
|
14
|
+
@industry = data[TickerFetcher::Retriever::Industry]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/test/helper.rb
CHANGED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'ticker_fetcher/retriever'
|
3
|
+
|
4
|
+
class TestRetriever < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@retriever = TickerFetcher::Retriever.new
|
7
|
+
@retriever.exchange_urls.each do |exchange, url|
|
8
|
+
FakeWeb.register_uri(
|
9
|
+
:get,
|
10
|
+
url,
|
11
|
+
:body => File.open("test/#{exchange.downcase}_test_data.csv").read)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_one_exchange
|
16
|
+
@retriever.run('NYSE')
|
17
|
+
assert_not_nil(@retriever.exchanges['NYSE'])
|
18
|
+
assert_nil(@retriever.exchanges['NASD'])
|
19
|
+
assert_nil(@retriever.exchanges['AMEX'])
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_retrieve_with_two_exchanges_returns_a_ticker_fetcher_with_two_exchanges
|
23
|
+
@retriever.run('NYSE')
|
24
|
+
@retriever.run('NASD')
|
25
|
+
assert_not_nil(@retriever.exchanges['NYSE'])
|
26
|
+
assert_not_nil(@retriever.exchanges['NASD'])
|
27
|
+
assert_nil(@retriever.exchanges['AMEX'])
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_retrieve_with_all_exchanges_returns_a_ticker_fetcher_with_all_exchanges
|
31
|
+
@retriever.run
|
32
|
+
@retriever.exchanges.keys.each do |exchange|
|
33
|
+
assert_not_nil(@retriever.exchanges[exchange])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_tickers
|
38
|
+
@retriever.run('NYSE')
|
39
|
+
assert_equal('SC', @retriever.exchanges['NYSE'].first.symbol)
|
40
|
+
assert_equal('ZGEN', @retriever.exchanges['NYSE'].last.symbol)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_company_names
|
44
|
+
@retriever.run('NYSE')
|
45
|
+
assert_equal('StupidCompany, Inc.', @retriever.exchanges['NYSE'].first.name)
|
46
|
+
assert_equal('ZymoGenetics, Inc.', @retriever.exchanges['NYSE'].last.name)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_last_sale_price
|
50
|
+
@retriever.run('NYSE')
|
51
|
+
assert_equal('2.71', @retriever.exchanges['NYSE'].first.last_sale)
|
52
|
+
assert_equal('25', @retriever.exchanges['NYSE'].last.last_sale)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_market_cap
|
56
|
+
@retriever.run('NYSE')
|
57
|
+
assert_equal('72858350', @retriever.exchanges['NYSE'].first.market_cap)
|
58
|
+
assert_equal('85473000', @retriever.exchanges['NYSE'].last.market_cap)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_ipo_year
|
62
|
+
@retriever.run('NYSE')
|
63
|
+
assert_equal('1999', @retriever.exchanges['NYSE'].first.ipo_year)
|
64
|
+
assert_equal('2015', @retriever.exchanges['NYSE'].last.ipo_year)
|
65
|
+
end
|
66
|
+
|
67
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_sector
|
68
|
+
@retriever.run('NYSE')
|
69
|
+
assert_equal('Consumer Services', @retriever.exchanges['NYSE'].first.sector)
|
70
|
+
assert_equal('Technology', @retriever.exchanges['NYSE'].last.sector)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_industry
|
74
|
+
@retriever.run('NYSE')
|
75
|
+
assert_equal('Other Specialty Stores', @retriever.exchanges['NYSE'].first.industry)
|
76
|
+
assert_equal('Semiconductors', @retriever.exchanges['NYSE'].last.industry)
|
77
|
+
end
|
78
|
+
end
|
data/test/test_stock.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'ticker_fetcher/stock'
|
3
|
+
|
4
|
+
class TestStock < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@symbol = 'TESTING'
|
7
|
+
@name = 'Testing, Inc.'
|
8
|
+
@last_sale = '1.23'
|
9
|
+
@market_cap = '123456789'
|
10
|
+
@ipo_year = '2000'
|
11
|
+
@sector = 'Consumer Services'
|
12
|
+
@industry = 'Other Specialty Stores'
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_create_a_stock
|
16
|
+
stock = TickerFetcher::Stock.new([@symbol, @name, @last_sale, @market_cap, @ipo_year, @sector, @industry])
|
17
|
+
assert_equal(@symbol, stock.symbol)
|
18
|
+
assert_equal(@name, stock.name)
|
19
|
+
assert_equal(@last_sale, stock.last_sale)
|
20
|
+
assert_equal(@market_cap, stock.market_cap)
|
21
|
+
assert_equal(@ipo_year, stock.ipo_year)
|
22
|
+
assert_equal(@sector, stock.sector)
|
23
|
+
assert_equal(@industry, stock.industry)
|
24
|
+
end
|
25
|
+
end
|
data/ticker_fetcher.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ticker_fetcher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-08-
|
12
|
+
date: 2011-08-12 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fakeweb
|
16
|
-
requirement: &
|
16
|
+
requirement: &80580980 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 1.3.0
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *80580980
|
25
25
|
description: Retrieves tickers, names, and other useful data for all stocks listed
|
26
26
|
on the 3 major US exchanges (NYSE, NASDAQ, AMEX).
|
27
27
|
email: mattw922@gmail.com
|
@@ -37,12 +37,14 @@ files:
|
|
37
37
|
- LICENSE
|
38
38
|
- README.rdoc
|
39
39
|
- Rakefile
|
40
|
-
- lib/ticker_fetcher.rb
|
40
|
+
- lib/ticker_fetcher/retriever.rb
|
41
|
+
- lib/ticker_fetcher/stock.rb
|
41
42
|
- test/amex_test_data.csv
|
42
43
|
- test/helper.rb
|
43
44
|
- test/nasd_test_data.csv
|
44
45
|
- test/nyse_test_data.csv
|
45
|
-
- test/
|
46
|
+
- test/test_retriever.rb
|
47
|
+
- test/test_stock.rb
|
46
48
|
- ticker_fetcher.gemspec
|
47
49
|
homepage: http://github.com/whitethunder/ticker_fetcher
|
48
50
|
licenses: []
|
data/lib/ticker_fetcher.rb
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'open-uri'
|
3
|
-
require 'csv'
|
4
|
-
|
5
|
-
class TickerFetcher
|
6
|
-
Symbol = 0
|
7
|
-
Name = 1
|
8
|
-
LastSale = 2
|
9
|
-
MarketCap = 3
|
10
|
-
IPOYear = 4
|
11
|
-
Sector = 5
|
12
|
-
Industry = 6
|
13
|
-
attr_reader :exchanges, :exchange_urls
|
14
|
-
|
15
|
-
# Passing an exchange name will retrieve only that exchange. Default is to retrieve all.
|
16
|
-
def initialize
|
17
|
-
@exchanges = {}
|
18
|
-
@exchange_urls = {
|
19
|
-
'AMEX' => 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=AMEX&render=download',
|
20
|
-
'NASD' => 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NASDAQ&render=download',
|
21
|
-
'NYSE' => 'http://www.nasdaq.com/screening/companies-by-industry.aspx?exchange=NYSE&render=download'
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
def retrieve(exchange=:all)
|
26
|
-
if exchange == :all
|
27
|
-
@exchange_urls.each { |exchange, url| @exchanges[exchange] = parse_exchange(exchange, url) }
|
28
|
-
else
|
29
|
-
@exchanges[exchange] = parse_exchange(exchange, @exchange_urls[exchange])
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def parse_exchange(exchange, url)
|
34
|
-
data = open(url)
|
35
|
-
parse_csv(data)
|
36
|
-
end
|
37
|
-
|
38
|
-
def [](exchange)
|
39
|
-
exchanges[exchange]
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def parse_csv(data)
|
45
|
-
CSV.parse(data, :headers => true).inject([]) do |tickers, row|
|
46
|
-
tickers << [ticker(row), name(row), last_sale(row), market_cap(row), ipo_year(row), sector(row), industry(row)]
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def name(row)
|
51
|
-
row[Name]
|
52
|
-
end
|
53
|
-
|
54
|
-
def ticker(row)
|
55
|
-
ticker = row[Symbol].strip.gsub('"', '')
|
56
|
-
unless(ticker.nil? || ticker.empty?)
|
57
|
-
ticker = ticker =~ /\W/ ? ticker.gsub('/', '.').gsub('^', '-') : ticker
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def last_sale(row)
|
62
|
-
row[LastSale]
|
63
|
-
end
|
64
|
-
|
65
|
-
def market_cap(row)
|
66
|
-
row[MarketCap]
|
67
|
-
end
|
68
|
-
|
69
|
-
def ipo_year(row)
|
70
|
-
row[IPOYear]
|
71
|
-
end
|
72
|
-
|
73
|
-
def sector(row)
|
74
|
-
row[Sector]
|
75
|
-
end
|
76
|
-
|
77
|
-
def industry(row)
|
78
|
-
row[Industry]
|
79
|
-
end
|
80
|
-
end
|
data/test/test_ticker_fetcher.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestTickerFetcher < Test::Unit::TestCase
|
4
|
-
def setup
|
5
|
-
@tf = TickerFetcher.new
|
6
|
-
@tf.exchange_urls.each do |exchange, url|
|
7
|
-
FakeWeb.register_uri(
|
8
|
-
:get,
|
9
|
-
url,
|
10
|
-
:body => File.open("test/#{exchange.downcase}_test_data.csv").read)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_one_exchange
|
15
|
-
@tf.retrieve('NYSE')
|
16
|
-
assert_not_nil(@tf.exchanges['NYSE'])
|
17
|
-
assert_nil(@tf.exchanges['NASD'])
|
18
|
-
assert_nil(@tf.exchanges['AMEX'])
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_retrieve_with_two_exchanges_returns_a_ticker_fetcher_with_two_exchanges
|
22
|
-
@tf.retrieve('NYSE')
|
23
|
-
@tf.retrieve('NASD')
|
24
|
-
assert_not_nil(@tf.exchanges['NYSE'])
|
25
|
-
assert_not_nil(@tf.exchanges['NASD'])
|
26
|
-
assert_nil(@tf.exchanges['AMEX'])
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_retrieve_with_all_exchanges_returns_a_ticker_fetcher_with_all_exchanges
|
30
|
-
@tf.retrieve
|
31
|
-
@tf.exchanges.keys.each do |exchange|
|
32
|
-
assert_not_nil(@tf.exchanges[exchange])
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_tickers
|
37
|
-
@tf.retrieve('NYSE')
|
38
|
-
assert_equal('SC', @tf.exchanges['NYSE'].first[TickerFetcher::Symbol])
|
39
|
-
assert_equal('ZGEN', @tf.exchanges['NYSE'].last[TickerFetcher::Symbol])
|
40
|
-
end
|
41
|
-
|
42
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_company_names
|
43
|
-
@tf.retrieve('NYSE')
|
44
|
-
assert_equal('StupidCompany, Inc.', @tf.exchanges['NYSE'].first[TickerFetcher::Name])
|
45
|
-
assert_equal('ZymoGenetics, Inc.', @tf.exchanges['NYSE'].last[TickerFetcher::Name])
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_last_sale_price
|
49
|
-
@tf.retrieve('NYSE')
|
50
|
-
assert_equal('2.71', @tf.exchanges['NYSE'].first[TickerFetcher::LastSale])
|
51
|
-
assert_equal('25', @tf.exchanges['NYSE'].last[TickerFetcher::LastSale])
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_market_cap
|
55
|
-
@tf.retrieve('NYSE')
|
56
|
-
assert_equal('72858350', @tf.exchanges['NYSE'].first[TickerFetcher::MarketCap])
|
57
|
-
assert_equal('85473000', @tf.exchanges['NYSE'].last[TickerFetcher::MarketCap])
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_ipo_year
|
61
|
-
@tf.retrieve('NYSE')
|
62
|
-
assert_equal('1999', @tf.exchanges['NYSE'].first[TickerFetcher::IPOYear])
|
63
|
-
assert_equal('2015', @tf.exchanges['NYSE'].last[TickerFetcher::IPOYear])
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_sector
|
67
|
-
@tf.retrieve('NYSE')
|
68
|
-
assert_equal('Consumer Services', @tf.exchanges['NYSE'].first[TickerFetcher::Sector])
|
69
|
-
assert_equal('Technology', @tf.exchanges['NYSE'].last[TickerFetcher::Sector])
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_retrieve_with_one_exchange_returns_a_ticker_fetcher_with_correct_industry
|
73
|
-
@tf.retrieve('NYSE')
|
74
|
-
assert_equal('Other Specialty Stores', @tf.exchanges['NYSE'].first[TickerFetcher::Industry])
|
75
|
-
assert_equal('Semiconductors', @tf.exchanges['NYSE'].last[TickerFetcher::Industry])
|
76
|
-
end
|
77
|
-
end
|