yahoo_finance_lib 0.7.9.9 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: bc13efc43548f4fc12c51b5f7d1c9b36a8c6debe
4
- data.tar.gz: b29a48bdee49e5dc63f45d697bcd3b1a98b83405
3
+ metadata.gz: 9df975c007b68670d21053d4074c84827e3d2c36
4
+ data.tar.gz: ac8125aa849e61edaaddac5f2eda9509612bf1fa
5
5
  SHA512:
6
- metadata.gz: d660f814fc921d549150357e6ab2de3a07f0cc76a2e6908d1d51c89ea26888f0aedc9a4ba814bc60bdb06a826e5944584d05a84e9981e37b30bdf7d2a99c38c6
7
- data.tar.gz: ed11f2b3faff77da3e4658182603826ab0b333beefd1179b6d7f6493c2a8cb0fc9dc3e1274fc097b29167e5f776d4ad2201753e3ef4308bcd70a7a746eabe580
6
+ metadata.gz: ab98ed7b73c1d7f070be411ee302c1376ea5b78bbf24431c98fed7081d65bf3603d98503f614154b28307f56a0d3c2b54a6e12adb2b72470161ea4b4301ef65e
7
+ data.tar.gz: ae1a07e599704f1f3c22232161f2f0c82255b641892a94f4905042348dd25266f3fb86dd37157cdac2fd7251a4e91fdb81ef7f55f1fc5ec82d11d9de5776941a
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # YahooFinance library
2
2
 
3
- YahooFinance lib is a gem that fetches stock quotes, key statistics, company profile, company events, and analyst opinion from Yahoo (TM) API and financial HTML pages. Additionally, it has interfaces for historical data, and financial statements. The loading of stock quotes uses the excellent nas/yahoo_stock gem. This gem provides a 'unified' attribute based interface, and abstracts the source of the information, i.e. the user only needs to specify an attribute without the need to specify the page source of the attribute. This gem leverages to the highest extend possible the YahooStock (yahoo_stock_nas) gem for all the attributes provided by that gem, and fails over to HTML scraping when the data is unavailable there. Naturally, this has an implication on performance; YahooStock queries bundle 50 stocks in each query, whereas HTML scraping happens one page per stock at a time.
3
+ YahooFinance lib is a gem that fetches stock quotes, key statistics, company profile, company events, analyst opinion, and analyst estimates from Yahoo (TM) API and financial HTML pages. Additionally, it has interfaces for historical data, and financial statements. The loading of stock quotes uses the excellent nas/yahoo_stock gem. This gem provides a 'unified' attribute based interface, and abstracts the source of the information, i.e. the user only needs to specify an attribute without the need to specify the page source of the attribute. This gem leverages to the highest extend possible the YahooStock (yahoo_stock_nas) gem for all the attributes provided by that gem, and fails over to HTML scraping when the data is unavailable there. Naturally, this has an implication on performance; YahooStock queries bundle 50 stocks in each query, whereas HTML scraping happens one page per stock at a time.
4
4
 
5
5
  #####This gem is currently still in development. HTML scraping now supports many attributes from Key Statistics, supports earnings announcements from the Company Events page, and most attributes from Analyst Opinion -- additional pages will be added as I find time.
6
6
 
@@ -28,7 +28,7 @@ Web pages get occasionally updated -- updates could break any or all of the clas
28
28
  ```
29
29
  rspec -c -f d
30
30
  ```
31
-
31
+ Beware that because the tests are based on actually fetching the data from yahoo, when the data structures fail, some tests that used to work may not work anymore. To be certain, you will need to investiage errors and subsequently investigate the yahoo page -- only then can you determine if the test works properly.
32
32
  ## Usage
33
33
 
34
34
 
@@ -77,7 +77,23 @@ A simple interface to scrape financial statements - Income Statement, Balance Sh
77
77
  ```
78
78
 
79
79
  The classes for the financial statement are: QuarterlyIncomeStatementPage, AnnualIncomeStatementPage, AnnualBalanceSheetPage, QuarterlyBalanceSheetPage, QuarterlyCashFlowStatementPage, AnnualCashFlowStatementPage
80
+
81
+ Release 1.0 brings a number of bug fixes from using the gem for almost a year now, as well as the addition of scraping the Analyst Estimates page. Each table in the analyst page is returned as a separate "field", namely :earnings_est, :revenue_est, :earnings_history, :EPS_trends, :EPS_revisions, and :growth_est. Fields are returned as hashes, with two keys: :columns and :values. The latter - :values - is another hash with keys the name of the row, and the value being that of an array of values (one for each column). For example:
82
+
83
+ ```ruby
84
+ irb
85
+ require 'yahoo_finance'
80
86
 
87
+ st = YahooFinance::Stock.new(['AAPL'])
88
+ st.add_field(:earnings_est)
89
+ result = st.fetch
90
+ ## result => {"AAPL"=>{:earnings_est=>{:columns=>["Current Qtr.Dec 15", "Next Qtr.Mar 16", "Current YearSep 16", "Next YearSep 17"], :values=>{"Avg. Estimate"=>[3.25, 2.38, 9.75, 10.7], "No. of Analysts"=>[40.0, 38.0, 49.0, 40.0], "Low Estimate"=>[2.96, 2.12, 8.92, 9.48], "High Estimate"=>[3.38, 2.84, 10.65, 12.26], "Year Ago EPS"=>[3.06, 2.33, 9.22, 9.75]}}}}
91
+ result['AAPL'][:earnings_est][:values]["Year Ago EPS"]
92
+ ## prints: [3.06, 2.33, 9.22, 9.75]
93
+ result['AAPL'][:earnings_est][:columns]
94
+ ## prints: ["Current Qtr.Dec 15", "Next Qtr.Mar 16", "Current YearSep 16", "Next YearSep 17"]
95
+ ```
96
+
81
97
  !-- ## Contributing
82
98
 
83
99
  1. Fork it
data/lib/yahoo_finance.rb CHANGED
@@ -5,6 +5,7 @@ require 'yahoo_finance/stock'
5
5
  require 'yahoo_finance/key_statistics'
6
6
  require 'yahoo_finance/company_events'
7
7
  require 'yahoo_finance/analyst_opinion'
8
+ require 'yahoo_finance/analyst_estimates'
8
9
  require 'yahoo_finance/company_profile'
9
10
  require 'yahoo_finance/financial_statement'
10
11
 
@@ -0,0 +1,82 @@
1
+ require 'open-uri'
2
+ require 'nokogiri'
3
+
4
+ module YahooFinance
5
+ module AnalystEstimates
6
+ AVL_KEY_STATS = {
7
+ :earnings_est => ['Earnings Est', "Earnings estimate table"],
8
+ :revenue_est => ['Revenue Est', "Revenue Estimate table"],
9
+ :earnings_history => ['Earnings History', 'Earnings History table'],
10
+ :EPS_trends => ['EPS Trends', 'EPS Trends table'],
11
+ :EPS_revisions => ['EPS Revisions', 'EPS Revisions table'],
12
+ :growth_est => ['Growth Estimate', 'Growth Estimate table']
13
+ }
14
+ def AnalystEstimates.key_events_available
15
+ return AVL_KEY_STATS.keys;
16
+ end
17
+
18
+ class AnalystEstimatesPage
19
+ attr_accessor :symbol
20
+
21
+ def initialize symbol=nil
22
+ @symbol = symbol
23
+ end
24
+
25
+ def fetch
26
+ url = "http://finance.yahoo.com/q/ae?s=#{@symbol}"
27
+ open(url) do |stream|
28
+ @doc = Nokogiri::HTML(stream)
29
+ # This page uses empty tables for spacing; they are all part of one cell. so table exist at positions 0,2,4,6,8,10
30
+ @tables = @doc.xpath("//table[@id = 'yfncsumtab']/tr[2]/td/table")
31
+ end
32
+ end
33
+
34
+ def value_for key_stat
35
+ begin
36
+ return nil if !AVL_KEY_STATS.keys.include?(key_stat)
37
+
38
+ ret = {}
39
+ # here we have to find the subtable that contains the data for key_stat
40
+ found = false
41
+ table_idx = nil
42
+ 0.upto(@tables.length) do |idx|
43
+ if @tables[idx].css("th").text.start_with?(AVL_KEY_STATS[key_stat][0])
44
+ found = true
45
+ table_idx = idx
46
+ break
47
+ end
48
+ end
49
+ return nil if !found
50
+
51
+ col_hdrs = @tables[table_idx].css("th")
52
+ # col_hdrs[0] is really the name of the table
53
+ return nil if col_hdrs[0].text != AVL_KEY_STATS[key_stat][0] # double check
54
+ hdrs = col_hdrs[1..(col_hdrs.length-1)].collect { |x| x.text }
55
+ ret[:columns] = hdrs
56
+ ret[:values] = {}
57
+
58
+ rows = @tables[table_idx].css("tr tr")
59
+ # rows[0] is the header
60
+ rows[1..(rows.length-1)].each do |row|
61
+ cells = row.css("td")
62
+ row_array = []
63
+ row_header = cells[0].text
64
+ cells[1..(cells.length-1)].each do |cell|
65
+ value = cell.text
66
+ begin
67
+ row_array << ((value == "N/A") ? "N/A" : YahooFinance.parse_yahoo_field(value))
68
+ rescue
69
+ puts "AnalystEstimatesPage: Could not parse yahoo field expected to be numeric"
70
+ end
71
+ end
72
+ ret[:values][row_header] = row_array
73
+ end
74
+
75
+ return ret
76
+ rescue
77
+ end
78
+ return nil
79
+ end
80
+ end
81
+ end
82
+ end
@@ -4,7 +4,8 @@ require 'nokogiri'
4
4
  module YahooFinance
5
5
  module CompanyEvents
6
6
  COMPANY_EVENTS_STATS = {
7
- :next_earnings_announcement_date => ['Earnings announcement', "Next earnings call date"]
7
+ :next_earnings_announcement_date => ['Earnings announcement', "Next earnings call date"],
8
+ :last_earnings_announcement_date => ['Earnings announcement', "Last earnings announcement date"]
8
9
  }
9
10
  def CompanyEvents.key_events_available
10
11
  return YahooFinance::CompanyEvents::COMPANY_EVENTS_STATS.keys;
@@ -30,6 +31,8 @@ module YahooFinance
30
31
  if @doc.css('table#yfncsumtab//table.yfnc_datamodoutline1//table//td.yfnc_tabledata1')[1].text == "Earnings announcement"
31
32
  return YahooFinance.parse_yahoo_field(@doc.css('table#yfncsumtab//table.yfnc_datamodoutline1//table//td.yfnc_tabledata1')[0].text)
32
33
  end
34
+ else
35
+ # these are previous events, and I need to look into a different table
33
36
  end
34
37
  rescue
35
38
  end
@@ -42,7 +42,7 @@ module YahooFinance
42
42
  :long_term_investments => ['Long Term Investments', 'Long Term Investments'],
43
43
  :property_plant_and_equipment => ['Property Plant and Equipment', 'Property Plant and Equipment'],
44
44
  :goodwill => ['Goodwill', 'Goodwill'],
45
- :intagible_assets => ['Intangible Assets', 'Intangible Assets'],
45
+ :intangible_assets => ['Intangible Assets', 'Intangible Assets'],
46
46
  :accumulated_amortization => ['Accumulated Amortization', 'Accumulated Amortization'],
47
47
  :other_assets => ['Other Assets', 'Other Assets'],
48
48
  :deferred_long_term_asset_charges => ['Deferred Long Term Asset Charges', 'Deferred Long Term Asset Charges'],
@@ -118,7 +118,22 @@ module YahooFinance
118
118
  return @field_defs.keys;
119
119
  end
120
120
 
121
+ # we use this to retry one more time; once in a while, it returns a valid page, but the page contains garbage
121
122
  def fetch
123
+ tries = 0
124
+ begin
125
+ return _fetch
126
+ rescue
127
+ tries += 1
128
+ if tries <= 1
129
+ puts "Exception: #{$!.inspect} -- Retrying symbol #{@symbol} (appears to be the problem of server error returning server error page)"
130
+ sleep(2)
131
+ retry
132
+ end
133
+ end
134
+ end
135
+
136
+ def _fetch
122
137
  url = "http://finance.yahoo.com/q/#{@type}?s=#{@symbol}&#{@term.to_s}"
123
138
  doc = nil
124
139
  tries = 0
@@ -7,6 +7,8 @@ module YahooFinance
7
7
  # String_to_parse, Description, Source Value format factor (some values are in % but dont't show %)
8
8
  :market_cap => ['Market Cap ', "Market Cap, intraday"],
9
9
  :enterprise_value => ['Enterprise Value ', "Enterprise Value"],
10
+ :enterprise_value_to_ebitda => ['Enterprise Value\/EBITDA \(ttm\)', "Enterprise Value/EBITDA"],
11
+ :ebitda => ['EBITDA \(ttm\)', 'Earnings before Income/Taxes/Depreciation'],
10
12
  :trailing_pe => ['Trailing P\/E \(ttm\, intraday\)\:', "Trailing PE, trailing twelve months, intraday (based on price)"],
11
13
  :forward_pe => ['Forward P\/E ', "Forward P/E"],
12
14
  :peg_ratio => ['PEG Ratio ', "PEG Ratio (5 year expected (forward looking))"],
@@ -14,7 +16,6 @@ module YahooFinance
14
16
  :price_to_book_mrq => ['Price\/Book \(mrq\):', "Price/Book, most recent quarter"],
15
17
  :roa_ttm => ['Return on Assets \(ttm\)\:', "Return on Assets, trailing twelve months"],
16
18
  :roe_ttm => ['Return on Equity \(ttm\)\:', "Return on Equity, trailing twelve months"],
17
- :book_value_per_share_mrq => ['Book Value Per Share \(mrq\):', "Book Value per share, most recent quarter"],
18
19
  # Income Statement
19
20
  :revenue_ttm => ['Revenue \(ttm\)\:', "Revenue, trailing twelve months"],
20
21
  :revenue_per_share_ttm => ['Revenue Per Share \(ttm\)\:', "Revenue per share, trailing twelve months"],
@@ -3,6 +3,7 @@ require 'yahoo_stock'
3
3
  require 'yahoo_finance/key_statistics'
4
4
  require 'yahoo_finance/company_events'
5
5
  require 'yahoo_finance/analyst_opinion'
6
+ require 'yahoo_finance/analyst_estimates'
6
7
  require 'yahoo_finance/company_profile'
7
8
 
8
9
 
@@ -12,12 +13,14 @@ module YahooFinance
12
13
  :KEY_STATISTICS => YahooFinance::KeyStatistics.key_stats_available,
13
14
  :COMPANY_EVENTS => YahooFinance::CompanyEvents.key_events_available,
14
15
  :ANALYST_OPINION => YahooFinance::AnalystOpinion.key_events_available,
16
+ :ANALYST_ESTIMATES => YahooFinance::AnalystEstimates.key_events_available,
15
17
  :COMPANY_PROFILE => YahooFinance::CompanyProfile.key_events_available
16
18
  }
17
19
  DRIVERS = {
18
20
  :KEY_STATISTICS => YahooFinance::KeyStatistics::StatsPage,
19
21
  :COMPANY_EVENTS => YahooFinance::CompanyEvents::CompanyEventsPage,
20
22
  :ANALYST_OPINION => YahooFinance::AnalystOpinion::AnalystOpinionPage,
23
+ :ANALYST_ESTIMATES => YahooFinance::AnalystEstimates::AnalystEstimatesPage,
21
24
  :COMPANY_PROFILE => YahooFinance::CompanyProfile::CompanyProfilePage
22
25
  }
23
26
 
@@ -121,7 +124,7 @@ module YahooFinance
121
124
 
122
125
  class Stock
123
126
  attr_reader :results_hash, :print_progress
124
- @@available_fields = (AVL_FIELDS[:YAHOO_STOCK_FIELDS] + AVL_FIELDS[:KEY_STATISTICS] + AVL_FIELDS[:COMPANY_EVENTS] + AVL_FIELDS[:ANALYST_OPINION] + AVL_FIELDS[:COMPANY_PROFILE])
127
+ @@available_fields = (AVL_FIELDS[:YAHOO_STOCK_FIELDS] + AVL_FIELDS[:KEY_STATISTICS] + AVL_FIELDS[:COMPANY_EVENTS] + AVL_FIELDS[:ANALYST_OPINION] + AVL_FIELDS[:ANALYST_ESTIMATES] + AVL_FIELDS[:COMPANY_PROFILE])
125
128
  @@insert_variable_delays = false
126
129
  @@insert_variable_delay = 2
127
130
  @@retry_times = 3
@@ -1,3 +1,3 @@
1
1
  module YahooFinance
2
- VERSION = "0.7.9.9"
2
+ VERSION = "1.0"
3
3
  end
@@ -0,0 +1,22 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe YahooFinance::AnalystEstimates do
4
+ # before(:each) do
5
+ # @tsymbols = ['AAPL', 'DDD']
6
+ # @page = YahooFinance::Page.new(@tsymbols)
7
+ # end
8
+
9
+ describe "Analyst Opinion" do
10
+ it "available stats should include things like :EPS_trends and :earnings_history" do
11
+ YahooFinance::AnalystEstimates.key_events_available.include?(:EPS_trends).should == true
12
+ YahooFinance::AnalystEstimates.key_events_available.include?(:earnings_history).should == true
13
+ end
14
+ it "should fetch a stat like :earnings_est for AAPL and should not be zero" do
15
+ pg = YahooFinance::AnalystEstimates::AnalystEstimatesPage.new('AAPL')
16
+ pg.fetch
17
+ aapl_earning_estimates = pg.value_for :earnings_est
18
+ aapl_earning_estimates[:columns].length.should > 0
19
+ aapl_earning_estimates[:values]['Avg. Estimate'].length.should > 0
20
+ end
21
+ end
22
+ end
@@ -13,8 +13,8 @@ describe YahooFinance::FinancialStatement do
13
13
  it "Income Statement should include things like :next_earnings_announcement_date" do
14
14
  YahooFinance::FinancialStatement::INCOME_STMT_FIELDS.include?(:operating_income_or_loss).should == true
15
15
  end
16
- it "Balance Sheet should include things like :intagible_assets" do
17
- YahooFinance::FinancialStatement::BALANCE_SHEET_FIELDS.include?(:intagible_assets).should == true
16
+ it "Balance Sheet should include things like :intangible_assets" do
17
+ YahooFinance::FinancialStatement::BALANCE_SHEET_FIELDS.include?(:intangible_assets).should == true
18
18
  end
19
19
  it "Cash Flow Statement should include things like :total_cash_flow_from_operating_activities" do
20
20
  YahooFinance::FinancialStatement::CASH_FLOW_STMT_FIELDS.include?(:total_cash_flow_from_operating_activities).should == true
@@ -91,18 +91,19 @@ describe YahooFinance::FinancialStatement do
91
91
  end
92
92
  end
93
93
  end
94
- it "should fetch all fields for e.g. ACT (3 quarters only on 11/19/14) quarterly Cash Flow statement and all values should be float (except for :statement_periods)-- valid values" do
95
- is = YahooFinance::FinancialStatement::QuarterlyCashFlowStatementPage.new 'ACT'
96
- rs = is.fetch
97
- YahooFinance::FinancialStatement::CASH_FLOW_STMT_FIELDS.keys.each do |attr|
98
- fields = rs[attr]
99
- fields.class.name.should == "Array"
100
- fields.size.should == 3
101
- fields.each do |field|
102
- attr == :statement_periods ? field.class.name.should == "Date" : field.class.name.should == "Float"
103
- end
104
- end
105
- end
94
+ # THE FOLLOWING NOW ACTUALLY FINDS FINANCIAL STATEMENTS, SO THE DATA PROBLEM IS FIXED
95
+ # it "should fetch all fields for e.g. ACT (3 quarters only on 11/19/14) quarterly Cash Flow statement and all values should be float (except for :statement_periods)-- valid values" do
96
+ # is = YahooFinance::FinancialStatement::QuarterlyCashFlowStatementPage.new 'ACT'
97
+ # rs = is.fetch
98
+ # YahooFinance::FinancialStatement::CASH_FLOW_STMT_FIELDS.keys.each do |attr|
99
+ # fields = rs[attr]
100
+ # fields.class.name.should == "Array"
101
+ # fields.size.should == 3
102
+ # fields.each do |field|
103
+ # attr == :statement_periods ? field.class.name.should == "Date" : field.class.name.should == "Float"
104
+ # end
105
+ # end
106
+ # end
106
107
  it "should return a nil hash if yahoo doesn't have the statement, e.g. for AMBR" do
107
108
  is = YahooFinance::FinancialStatement::QuarterlyCashFlowStatementPage.new 'AMBR'
108
109
  rs = is.fetch
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = YahooFinance::VERSION
9
9
  spec.authors = ["Takis Mercouris"]
10
10
  spec.email = ["tm@polymechanus.com"]
11
- spec.description = %q{Unified library to stock quotes and various pages in yahoo finance, including key statistics, company events, and analyst opinion}
11
+ spec.description = %q{Unified library to stock quotes and various pages in yahoo finance, including key statistics, company events, analyst estimates, analyst opinion, and financial statements}
12
12
  spec.summary = %q{Fetch stock information from yahoo finance API and HTML pages}
13
13
  spec.homepage = "http://polymechanus.com/yahoo_finance-ruby-gem-tutorial/"
14
14
  spec.license = "MIT"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yahoo_finance_lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.9.9
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Takis Mercouris
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-25 00:00:00.000000000 Z
11
+ date: 2016-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nas-yahoo_stock
@@ -99,7 +99,8 @@ dependencies:
99
99
  - !ruby/object:Gem::Version
100
100
  version: 2.14.1
101
101
  description: Unified library to stock quotes and various pages in yahoo finance, including
102
- key statistics, company events, and analyst opinion
102
+ key statistics, company events, analyst estimates, analyst opinion, and financial
103
+ statements
103
104
  email:
104
105
  - tm@polymechanus.com
105
106
  executables: []
@@ -113,6 +114,7 @@ files:
113
114
  - README.md
114
115
  - Rakefile
115
116
  - lib/yahoo_finance.rb
117
+ - lib/yahoo_finance/analyst_estimates.rb
116
118
  - lib/yahoo_finance/analyst_opinion.rb
117
119
  - lib/yahoo_finance/company_events.rb
118
120
  - lib/yahoo_finance/company_profile.rb
@@ -121,6 +123,7 @@ files:
121
123
  - lib/yahoo_finance/stock.rb
122
124
  - lib/yahoo_finance/version.rb
123
125
  - spec/spec_helper.rb
126
+ - spec/yahoo_analyst_estimates_spec.rb
124
127
  - spec/yahoo_analyst_opinion_spec.rb
125
128
  - spec/yahoo_company_events_spec.rb
126
129
  - spec/yahoo_company_profile_spec.rb
@@ -148,12 +151,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
151
  version: '0'
149
152
  requirements: []
150
153
  rubyforge_project:
151
- rubygems_version: 2.4.2
154
+ rubygems_version: 2.4.8
152
155
  signing_key:
153
156
  specification_version: 4
154
157
  summary: Fetch stock information from yahoo finance API and HTML pages
155
158
  test_files:
156
159
  - spec/spec_helper.rb
160
+ - spec/yahoo_analyst_estimates_spec.rb
157
161
  - spec/yahoo_analyst_opinion_spec.rb
158
162
  - spec/yahoo_company_events_spec.rb
159
163
  - spec/yahoo_company_profile_spec.rb