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.
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/attributes'
4
+ require 'stock_index/indices'
4
5
  require 'stock_index/market'
5
- require 'stock_index/scrapers/dji_scraper'
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
@@ -1,5 +1,5 @@
1
1
  class StockIndex
2
- ATTRIBUTES = {
2
+ INDICES = {
3
3
  '^DJI' => {
4
4
  name: 'DOW JONES INDUSTRIAL AVERAGE',
5
5
  url: 'http://en.wikipedia.org/wiki/Dow_Jones_Industrial_Average'
@@ -8,9 +8,9 @@ class StockIndex
8
8
 
9
9
  def to_iso10383
10
10
  case @market
11
- when 'NYSE'
11
+ when 'NYSE', 'www.nyse.com'
12
12
  'XNYS'
13
- when 'NASDAQ'
13
+ when 'NASDAQ', 'www.nasdaq.com'
14
14
  'XNAS'
15
15
  end
16
16
  end
@@ -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::ATTRIBUTES['^DJI'][:url]))
5
- doc.css('table.wikitable.sortable tr').inject([]) do |array, 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.css('td')[2]
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.css('td')[1]
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
@@ -1,7 +1,5 @@
1
1
  class StockIndex
2
2
 
3
- require 'nokogiri'
4
-
5
3
  def initialize(symbol)
6
4
  @symbol = symbol
7
5
  end
@@ -10,6 +8,8 @@ class StockIndex
10
8
  case @symbol
11
9
  when '^DJI'
12
10
  DjiScraper.new.scrape
11
+ when '^GSPC'
12
+ SP500Scraper.new.scrape
13
13
  else
14
14
  []
15
15
  end
@@ -1,3 +1,3 @@
1
1
  class StockIndex
2
- VERSION = "0.5.0"
2
+ VERSION = "0.5.1"
3
3
  end
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.0
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-23 00:00:00.000000000 Z
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/attributes.rb
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: {}