stock_index 0.5.0 → 0.5.1
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.
- checksums.yaml +4 -4
- data/README.md +20 -2
- data/cache/data.pstore +0 -0
- data/csv/US.csv +884 -547
- data/lib/stock_index.rb +7 -2
- data/lib/stock_index/bsym_search.rb +23 -0
- data/lib/stock_index/component.rb +57 -0
- data/lib/stock_index/{attributes.rb → indices.rb} +1 -1
- data/lib/stock_index/market.rb +2 -2
- data/lib/stock_index/scrapers/SP500_scraper.rb +46 -0
- data/lib/stock_index/scrapers/base_scraper.rb +31 -0
- data/lib/stock_index/scrapers/dji_scraper.rb +11 -11
- data/lib/stock_index/stock_index.rb +2 -2
- data/lib/stock_index/version.rb +1 -1
- data/stock_index.gemspec +2 -1
- metadata +23 -4
data/lib/stock_index.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
require 'pstore'
|
1
2
|
require 'stock_index/version'
|
2
3
|
require 'stock_index/stock_index'
|
3
|
-
require 'stock_index/
|
4
|
+
require 'stock_index/indices'
|
4
5
|
require 'stock_index/market'
|
5
|
-
require 'stock_index/
|
6
|
+
require 'stock_index/component'
|
7
|
+
require 'stock_index/bsym_search'
|
8
|
+
require 'stock_index/scrapers/base_scraper'
|
9
|
+
require 'stock_index/scrapers/dji_scraper'
|
10
|
+
require 'stock_index/scrapers/SP500_scraper'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class StockIndex
|
2
|
+
|
3
|
+
class BsymSearch
|
4
|
+
|
5
|
+
require 'csv'
|
6
|
+
|
7
|
+
FILES = {
|
8
|
+
us: 'csv/US.csv'
|
9
|
+
}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def find(symbol, pricing_source = :us)
|
14
|
+
CSV.foreach(FILES[pricing_source]) do |row|
|
15
|
+
return {name: row[1], bbgid: row[2]} if row[0] == symbol
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class StockIndex
|
2
|
+
|
3
|
+
class Component
|
4
|
+
|
5
|
+
require 'cik'
|
6
|
+
|
7
|
+
def initialize(symbol, market, wikipedia)
|
8
|
+
@symbol = symbol
|
9
|
+
@market = market
|
10
|
+
@wikipedia = wikipedia
|
11
|
+
end
|
12
|
+
|
13
|
+
def attributes
|
14
|
+
cache_lookup || attributes_lookup
|
15
|
+
end
|
16
|
+
|
17
|
+
def valid?
|
18
|
+
@market && @symbol
|
19
|
+
end
|
20
|
+
|
21
|
+
def cache_lookup
|
22
|
+
store = PStore.new('cache/data.pstore')
|
23
|
+
store.transaction { store[@symbol] }
|
24
|
+
end
|
25
|
+
|
26
|
+
def cache_write(a)
|
27
|
+
store = PStore.new('cache/data.pstore')
|
28
|
+
store.transaction do
|
29
|
+
store[@symbol] = a
|
30
|
+
end
|
31
|
+
a
|
32
|
+
end
|
33
|
+
|
34
|
+
def attributes_lookup
|
35
|
+
puts "--> #{@symbol}"
|
36
|
+
bsym = StockIndex::BsymSearch.find(@symbol)
|
37
|
+
edgar = Cik.lookup(parse_symbol(@symbol))
|
38
|
+
a = {market: @market, symbol: @symbol, name: bsym[:name], wikipedia: @wikipedia, cik: edgar[:cik], bbgid: bsym[:bbgid]}
|
39
|
+
cache_write(a)
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_symbol(symbol)
|
43
|
+
case symbol
|
44
|
+
# BRK/B => 0001067983 Berkshire Hathaway Inc
|
45
|
+
# BF/B => 0000014693 Brown-Forman Corp
|
46
|
+
when 'BRK/B'
|
47
|
+
'0001067983'
|
48
|
+
when 'BF/B'
|
49
|
+
'0000014693'
|
50
|
+
else
|
51
|
+
symbol
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
data/lib/stock_index/market.rb
CHANGED
@@ -0,0 +1,46 @@
|
|
1
|
+
class SP500Scraper < StockIndex::BaseScraper
|
2
|
+
|
3
|
+
def scrape
|
4
|
+
doc = Nokogiri::HTML(open(StockIndex::INDICES['^GSPC'][:url]))
|
5
|
+
parse_rows doc.css('table.wikitable.sortable')[0].css('tr')
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def symbol(tr)
|
11
|
+
symbol_td = td(tr, 0)
|
12
|
+
s = symbol_td ? symbol_td.css('a').first.text : nil
|
13
|
+
parse_symbol(s)
|
14
|
+
end
|
15
|
+
|
16
|
+
def market(tr)
|
17
|
+
market_td = td(tr, 0)
|
18
|
+
market_link = market_td ? market_td.css('a').first.attributes['href'].value : nil
|
19
|
+
StockIndex::Market.new(parse_market_link(market_link)).to_iso10383
|
20
|
+
end
|
21
|
+
|
22
|
+
def wikipedia(tr)
|
23
|
+
wikipedia_position(tr, 1)
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_market_link(market_link)
|
27
|
+
if market_link
|
28
|
+
uri = URI(market_link)
|
29
|
+
uri.host
|
30
|
+
else
|
31
|
+
nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_symbol(symbol)
|
36
|
+
case symbol
|
37
|
+
# BRK.B => BRK/B Berkshire Hathaway Inc
|
38
|
+
# BF.B => BF/B Brown-Forman Corp
|
39
|
+
when /(\w+)\.B/
|
40
|
+
"#{$1}/B"
|
41
|
+
else
|
42
|
+
symbol
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
class StockIndex
|
2
|
+
|
3
|
+
class BaseScraper
|
4
|
+
|
5
|
+
require 'nokogiri'
|
6
|
+
|
7
|
+
def parse_rows(rows)
|
8
|
+
rows.inject([]) do |array, tr|
|
9
|
+
symbol = symbol(tr)
|
10
|
+
market = market(tr)
|
11
|
+
if symbol && market
|
12
|
+
component = StockIndex::Component.new(symbol, market, wikipedia(tr))
|
13
|
+
array << component.attributes if component.valid?
|
14
|
+
end
|
15
|
+
array
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def td(tr, position)
|
20
|
+
tr.css('td')[position]
|
21
|
+
end
|
22
|
+
|
23
|
+
def wikipedia_position(tr, position)
|
24
|
+
wikipedia_td = tr.css('td')[position]
|
25
|
+
wikipedia_path = wikipedia_td ? wikipedia_td.css('a').first.attributes['href'].value : nil
|
26
|
+
URI::HTTP.build({:host => 'en.wikipedia.org', :path => wikipedia_path}).to_s rescue nil
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -1,25 +1,25 @@
|
|
1
|
-
class DjiScraper
|
1
|
+
class DjiScraper < StockIndex::BaseScraper
|
2
2
|
|
3
3
|
def scrape
|
4
|
-
doc = Nokogiri::HTML(open(StockIndex::
|
5
|
-
doc.css('table.wikitable.sortable tr')
|
6
|
-
string = "#{market(tr)}:#{symbol(tr)}"
|
7
|
-
array << string unless string == ":"
|
8
|
-
array
|
9
|
-
end
|
4
|
+
doc = Nokogiri::HTML(open(StockIndex::INDICES['^DJI'][:url]))
|
5
|
+
parse_rows doc.css('table.wikitable.sortable tr')
|
10
6
|
end
|
11
7
|
|
12
8
|
private
|
13
9
|
|
14
10
|
def symbol(tr)
|
15
|
-
symbol_td = tr
|
16
|
-
symbol_td ? symbol_td.css('a').text : nil
|
11
|
+
symbol_td = td(tr, 2)
|
12
|
+
symbol_td ? symbol_td.css('a').first.text : nil
|
17
13
|
end
|
18
14
|
|
19
15
|
def market(tr)
|
20
|
-
market_td = tr
|
21
|
-
market = market_td ? market_td.css('a').text : nil
|
16
|
+
market_td = td(tr, 1)
|
17
|
+
market = market_td ? market_td.css('a').first.text : nil
|
22
18
|
StockIndex::Market.new(market).to_iso10383
|
23
19
|
end
|
24
20
|
|
21
|
+
def wikipedia(tr)
|
22
|
+
wikipedia_position(tr, 0)
|
23
|
+
end
|
24
|
+
|
25
25
|
end
|
data/lib/stock_index/version.rb
CHANGED
data/stock_index.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["javier@javiervidal.net"]
|
11
11
|
spec.summary = 'Stock Index'
|
12
12
|
spec.description = 'Stock Index'
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/javiervidal/stock_index"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "rspec"
|
25
25
|
spec.add_development_dependency "simplecov"
|
26
26
|
spec.add_runtime_dependency "nokogiri"
|
27
|
+
spec.add_runtime_dependency "cik"
|
27
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stock_index
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Javier Vidal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: cik
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: Stock Index
|
98
112
|
email:
|
99
113
|
- javier@javiervidal.net
|
@@ -106,15 +120,20 @@ files:
|
|
106
120
|
- LICENSE.txt
|
107
121
|
- README.md
|
108
122
|
- Rakefile
|
123
|
+
- cache/data.pstore
|
109
124
|
- csv/US.csv
|
110
125
|
- lib/stock_index.rb
|
111
|
-
- lib/stock_index/
|
126
|
+
- lib/stock_index/bsym_search.rb
|
127
|
+
- lib/stock_index/component.rb
|
128
|
+
- lib/stock_index/indices.rb
|
112
129
|
- lib/stock_index/market.rb
|
130
|
+
- lib/stock_index/scrapers/SP500_scraper.rb
|
131
|
+
- lib/stock_index/scrapers/base_scraper.rb
|
113
132
|
- lib/stock_index/scrapers/dji_scraper.rb
|
114
133
|
- lib/stock_index/stock_index.rb
|
115
134
|
- lib/stock_index/version.rb
|
116
135
|
- stock_index.gemspec
|
117
|
-
homepage:
|
136
|
+
homepage: https://github.com/javiervidal/stock_index
|
118
137
|
licenses:
|
119
138
|
- MIT
|
120
139
|
metadata: {}
|