stock_recommendation 0.0.1

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