stock_index 0.5.0 → 0.5.1

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