stock_recommendation 0.0.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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/stock_recommendation.rb +91 -0
  3. metadata +99 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b19eca5c4eb98f7e2a004e5b0637ced31ba570ac7d2cd0278bdc5e226f2ce917
4
+ data.tar.gz: 6fe6678678badd0f336fd1500f9a27f5fa54c01a79006e1aac5a3d1426516826
5
+ SHA512:
6
+ metadata.gz: 83114aee29b33f3639aecf5f2603a7366042b7480af2f858be6c0dcf1da31a6e2d9c71478b17d1d32a9c7ac44406328feb6b0f1ef2c23d79cb976bef36cab9b7
7
+ data.tar.gz: c1117edddb40c72353a581d5e806c1e9e0541f7345f27d1e70c5a21481d79d00440fa12b32451de11260fb33b729a597fc276426df143c4616a6dd5aa9c8a590
@@ -0,0 +1,91 @@
1
+ require 'rubygems'
2
+ require 'open-uri'
3
+ require 'nokogiri'
4
+
5
+ module StockRecommendation
6
+
7
+ class Recommendation
8
+
9
+ def self.get(stock_code)
10
+ result = get_stock_recommendation(stock_code)
11
+ Recommendation.new(result)
12
+ end
13
+
14
+ def to_hash
15
+ hash = {}
16
+ instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
17
+ hash
18
+ end
19
+
20
+ protected
21
+
22
+ def initialize(data={})
23
+ data.each {|k,v|
24
+ self.class.__send__(:attr_accessor, k.to_sym)
25
+ self.instance_variable_set("@#{k}".to_sym, v)
26
+ }
27
+ @response_code = !!([{}, nil, ''].include?(data)) ? 500 : 200
28
+ end
29
+
30
+ def self.get_stock_recommendation(stock_code)
31
+ document = fetch_recommendation(stock_code)
32
+ recommendations = extract_recommendation(document)
33
+ end
34
+
35
+ def self.fetch_recommendation(stock_code)
36
+ uri = 'https://www.reuters.com/finance/stocks/analyst/'
37
+ response = open(uri + stock_code)
38
+ @doc = Nokogiri::HTML(response);
39
+ raise "Unable to fetch recommendations data for stock {#{stock_code}}" if !@doc.at_css("#sectionTitle > h1")
40
+ end
41
+
42
+ def self.extract_recommendation(document)
43
+ recommendations = {}
44
+ modules = @doc.xpath('//div[@class="module"]')
45
+ recommendations["title"] = @doc.css("#sectionTitle > h1").text()
46
+ modules.each do |m|
47
+ if m.css("div.moduleHeader > h3").text().strip! == 'Consensus Recommendations'
48
+ recommendations["consensus_recommendation"] = m.css("div.moduleBody > table > tbody > tr.stripe > td:nth-child(1)").text()
49
+ recommendations["date_updated"] = m.css("div.moduleBody > table > tbody > tr.stripe > td:nth-child(4)").text()
50
+ elsif m.css("div.moduleHeader > h3").text().strip! == 'Analyst Recommendations and Revisions'
51
+ rows = m.css("div.moduleBody > table > tbody > tr")
52
+ rows.each do |row|
53
+ if row.css("td:nth-child(1)").text().include? "BUY"
54
+ recommendations["votes_buy"] = row.css("td:nth-child(2)").text().to_i
55
+ recommendations["votes_buy_one_month_ago"] = row.css("td:nth-child(3)").text().to_i
56
+ recommendations["votes_buy_two_months_ago"] = row.css("td:nth-child(4)").text().to_i
57
+ recommendations["votes_buy_three_months_ago"] = row.css("td:nth-child(5)").text().to_i
58
+ elsif row.css("td:nth-child(1)").text().include? "SELL"
59
+ recommendations["votes_sell"] = row.css("td:nth-child(2)").text().to_i
60
+ recommendations["votes_sell_one_month_ago"] = row.css("td:nth-child(3)").text().to_i
61
+ recommendations["votes_sell_two_months_ago"] = row.css("td:nth-child(4)").text().to_i
62
+ recommendations["votes_sell_three_months_ago"] = row.css("td:nth-child(5)").text().to_i
63
+ elsif row.css("td:nth-child(1)").text().include? "HOLD"
64
+ recommendations["votes_hold"] = row.css("td:nth-child(2)").text().to_i
65
+ recommendations["votes_hold_one_month_ago"] = row.css("td:nth-child(3)").text().to_i
66
+ recommendations["votes_hold_two_months_ago"] = row.css("td:nth-child(4)").text().to_i
67
+ recommendations["votes_hold_three_months_ago"] = row.css("td:nth-child(5)").text().to_i
68
+ elsif row.css("td:nth-child(1)").text().include? "OUTPERFORM"
69
+ recommendations["votes_outperform"] = row.css("td:nth-child(2)").text().to_i
70
+ recommendations["votes_outperform_one_month_ago"] = row.css("td:nth-child(3)").text().to_i
71
+ recommendations["votes_outperform_two_months_ago"] = row.css("td:nth-child(4)").text().to_i
72
+ recommendations["votes_outperform_three_month_ago"] = row.css("td:nth-child(5)").text().to_i
73
+ elsif row.css("td:nth-child(1)").text().include? "UNDERPERFORM"
74
+ recommendations["votes_underperform"] = row.css("td:nth-child(2)").text().to_i
75
+ recommendations["votes_underperform_one_month_ago"] = row.css("td:nth-child(3)").text().to_i
76
+ recommendations["votes_underperform_two_months_ago"] = row.css("td:nth-child(4)").text().to_i
77
+ recommendations["votes_underperform_three_months_ago"] = row.css("td:nth-child(5)").text().to_i
78
+ elsif row.css("td:nth-child(1)").text().include? "No Opinion"
79
+ recommendations["votes_no_opinion"] = row.css("td:nth-child(2)").text().to_i
80
+ recommendations["votes_no_opinion_one_month_ago"] = row.css("td:nth-child(3)").text().to_i
81
+ recommendations["votes_no_opinion_two_months_ago"] = row.css("td:nth-child(4)").text().to_i
82
+ recommendations["votes_no_opinion_three_months_ago"] = row.css("td:nth-child(5)").text().to_i
83
+ end
84
+ end
85
+ end
86
+ end
87
+ recommendations
88
+ end
89
+
90
+ end
91
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stock_recommendation
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Leonid Brujev brujev@gmail.com
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-12-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - lib/stock_recommendation.rb
76
+ homepage:
77
+ licenses: []
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.7.3
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: stock_recommendation is the best
99
+ test_files: []