finmodeling 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +0 -0
- data/Gemfile +2 -0
- data/README.md +289 -269
- data/Rakefile +12 -0
- data/TODO.txt +113 -20
- data/examples/{dump_report.rb → dump_latest_10k.rb} +1 -1
- data/examples/list_disclosures.rb +50 -0
- data/examples/lists/nasdaq-mid-to-mega-tech-symbols.txt +0 -0
- data/examples/show_report.rb +112 -32
- data/examples/show_reports.rb +162 -33
- data/finmodeling.gemspec +4 -1
- data/lib/finmodeling/annual_report_filing.rb +97 -18
- data/lib/finmodeling/array_with_stats.rb +0 -0
- data/lib/finmodeling/assets_calculation.rb +12 -3
- data/lib/finmodeling/assets_item.rb +0 -0
- data/lib/finmodeling/assets_item_vectors.rb +0 -0
- data/lib/finmodeling/balance_sheet_analyses.rb +19 -4
- data/lib/finmodeling/balance_sheet_calculation.rb +52 -37
- data/lib/finmodeling/calculation_summary.rb +119 -14
- data/lib/finmodeling/can_cache_classifications.rb +0 -0
- data/lib/finmodeling/can_cache_summaries.rb +0 -0
- data/lib/finmodeling/can_choose_successive_periods.rb +15 -0
- data/lib/finmodeling/can_classify_rows.rb +0 -0
- data/lib/finmodeling/capm.rb +80 -0
- data/lib/finmodeling/cash_change_calculation.rb +3 -3
- data/lib/finmodeling/cash_change_item.rb +0 -0
- data/lib/finmodeling/cash_change_item_vectors.rb +0 -0
- data/lib/finmodeling/cash_change_summary_from_differences.rb +36 -0
- data/lib/finmodeling/cash_flow_statement_analyses.rb +36 -0
- data/lib/finmodeling/cash_flow_statement_calculation.rb +28 -52
- data/lib/finmodeling/classifiers.rb +2 -0
- data/lib/finmodeling/company.rb +0 -0
- data/lib/finmodeling/company_filing.rb +30 -7
- data/lib/finmodeling/company_filing_calculation.rb +16 -6
- data/lib/finmodeling/company_filings.rb +112 -46
- data/lib/finmodeling/comprehensive_income_calculation.rb +60 -0
- data/lib/finmodeling/comprehensive_income_statement_calculation.rb +74 -0
- data/lib/finmodeling/comprehensive_income_statement_item.rb +20 -0
- data/lib/finmodeling/comprehensive_income_statement_item_vectors.rb +235 -0
- data/lib/finmodeling/config.rb +0 -0
- data/lib/finmodeling/debt_cost_of_capital.rb +14 -0
- data/lib/finmodeling/equity_change_calculation.rb +43 -0
- data/lib/finmodeling/equity_change_item.rb +25 -0
- data/lib/finmodeling/equity_change_item_vectors.rb +156 -0
- data/lib/finmodeling/factory.rb +0 -0
- data/lib/finmodeling/fama_french_cost_of_equity.rb +119 -0
- data/lib/finmodeling/float_helpers.rb +14 -8
- data/lib/finmodeling/forecasted_reformulated_balance_sheet.rb +55 -0
- data/lib/finmodeling/forecasted_reformulated_income_statement.rb +110 -0
- data/lib/finmodeling/forecasts.rb +4 -4
- data/lib/finmodeling/has_string_classifer.rb +0 -0
- data/lib/finmodeling/income_statement_analyses.rb +23 -17
- data/lib/finmodeling/income_statement_calculation.rb +46 -43
- data/lib/finmodeling/income_statement_item.rb +1 -1
- data/lib/finmodeling/income_statement_item_vectors.rb +24 -13
- data/lib/finmodeling/invalid_filing_error.rb +4 -0
- data/lib/finmodeling/liabs_and_equity_calculation.rb +18 -8
- data/lib/finmodeling/liabs_and_equity_item.rb +1 -1
- data/lib/finmodeling/liabs_and_equity_item_vectors.rb +24 -24
- data/lib/finmodeling/linear_trend_forecasting_policy.rb +23 -0
- data/lib/finmodeling/net_income_calculation.rb +23 -10
- data/lib/finmodeling/net_income_summary_from_differences.rb +51 -0
- data/lib/finmodeling/paths.rb +0 -0
- data/lib/finmodeling/period_array.rb +8 -4
- data/lib/finmodeling/quarterly_report_filing.rb +9 -4
- data/lib/finmodeling/rate.rb +8 -0
- data/lib/finmodeling/ratio.rb +0 -0
- data/lib/finmodeling/reformulated_balance_sheet.rb +47 -88
- data/lib/finmodeling/reformulated_cash_flow_statement.rb +18 -41
- data/lib/finmodeling/reformulated_income_statement.rb +44 -206
- data/lib/finmodeling/reformulated_shareholder_equity_statement.rb +50 -0
- data/lib/finmodeling/reoi_valuation.rb +104 -0
- data/lib/finmodeling/shareholder_equity_statement_calculation.rb +34 -0
- data/lib/finmodeling/string_helpers.rb +18 -1
- data/lib/finmodeling/time_series_estimator.rb +25 -0
- data/lib/finmodeling/trailing_avg_forecasting_policy.rb +23 -0
- data/lib/finmodeling/version.rb +1 -1
- data/lib/finmodeling/weighted_avg_cost_of_capital.rb +35 -0
- data/lib/finmodeling/yahoo_finance_helpers.rb +20 -0
- data/lib/finmodeling.rb +33 -2
- data/spec/annual_report_filing_spec.rb +81 -45
- data/spec/assets_calculation_spec.rb +7 -4
- data/spec/assets_item_spec.rb +9 -14
- data/spec/balance_sheet_analyses_spec.rb +13 -13
- data/spec/balance_sheet_calculation_spec.rb +45 -51
- data/spec/calculation_summary_spec.rb +113 -21
- data/spec/can_classify_rows_spec.rb +0 -0
- data/spec/cash_change_calculation_spec.rb +1 -10
- data/spec/cash_change_item_spec.rb +10 -18
- data/spec/cash_flow_statement_calculation_spec.rb +10 -24
- data/spec/company_beta_spec.rb +53 -0
- data/spec/company_filing_calculation_spec.rb +39 -49
- data/spec/company_filing_spec.rb +0 -0
- data/spec/company_filings_spec.rb +75 -25
- data/spec/company_spec.rb +37 -47
- data/spec/comprehensive_income_statement_calculation_spec.rb +54 -0
- data/spec/comprehensive_income_statement_item_spec.rb +56 -0
- data/spec/debt_cost_of_capital_spec.rb +19 -0
- data/spec/equity_change_calculation_spec.rb +33 -0
- data/spec/equity_change_item_spec.rb +58 -0
- data/spec/factory_spec.rb +2 -2
- data/spec/forecasts_spec.rb +2 -2
- data/spec/income_statement_analyses_spec.rb +23 -21
- data/spec/income_statement_calculation_spec.rb +17 -49
- data/spec/income_statement_item_spec.rb +17 -29
- data/spec/liabs_and_equity_calculation_spec.rb +6 -3
- data/spec/liabs_and_equity_item_spec.rb +14 -22
- data/spec/linear_trend_forecasting_policy_spec.rb +37 -0
- data/spec/matchers/custom_matchers.rb +79 -0
- data/spec/mocks/calculation.rb +0 -0
- data/spec/mocks/income_statement_analyses.rb +0 -0
- data/spec/mocks/sec_query.rb +0 -0
- data/spec/net_income_calculation_spec.rb +16 -10
- data/spec/period_array.rb +0 -0
- data/spec/quarterly_report_filing_spec.rb +21 -38
- data/spec/rate_spec.rb +0 -0
- data/spec/ratio_spec.rb +0 -0
- data/spec/reformulated_balance_sheet_spec.rb +56 -33
- data/spec/reformulated_cash_flow_statement_spec.rb +18 -10
- data/spec/reformulated_income_statement_spec.rb +16 -15
- data/spec/reformulated_shareholder_equity_statement_spec.rb +43 -0
- data/spec/reoi_valuation_spec.rb +146 -0
- data/spec/shareholder_equity_statement_calculation_spec.rb +59 -0
- data/spec/spec_helper.rb +4 -1
- data/spec/string_helpers_spec.rb +15 -13
- data/spec/time_series_estimator_spec.rb +61 -0
- data/spec/trailing_avg_forecasting_policy_spec.rb +37 -0
- data/spec/weighted_avg_cost_of_capital_spec.rb +32 -0
- data/tools/create_equity_change_training_vectors.rb +49 -0
- data/tools/time_specs.sh +7 -0
- metadata +182 -36
- data/lib/finmodeling/constant_forecasting_policy.rb +0 -23
- data/lib/finmodeling/generic_forecasting_policy.rb +0 -19
- data/spec/constant_forecasting_policy_spec.rb +0 -37
- data/spec/generic_forecasting_policy_spec.rb +0 -33
@@ -0,0 +1,23 @@
|
|
1
|
+
module FinModeling
|
2
|
+
class TrailingAvgForecastingPolicy
|
3
|
+
def initialize(args)
|
4
|
+
@vals = args
|
5
|
+
end
|
6
|
+
|
7
|
+
def revenue_on(date)
|
8
|
+
@vals[:revenue_estimator].estimate_on(date)
|
9
|
+
end
|
10
|
+
|
11
|
+
def sales_pm_on(date)
|
12
|
+
@vals[:sales_pm_estimator].estimate_on(date)
|
13
|
+
end
|
14
|
+
|
15
|
+
def fi_over_nfa_on(date)
|
16
|
+
@vals[:fi_over_nfa_estimator].estimate_on(date)
|
17
|
+
end
|
18
|
+
|
19
|
+
def sales_over_noa_on(date)
|
20
|
+
@vals[:sales_over_noa_estimator].estimate_on(date)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/finmodeling/version.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
module FinModeling
|
2
|
+
class WeightedAvgCostOfCapital
|
3
|
+
attr_reader :rate
|
4
|
+
|
5
|
+
def initialize(equity_market_val, debt_market_val, cost_of_equity, after_tax_cost_of_debt)
|
6
|
+
@equity_market_val = equity_market_val
|
7
|
+
@debt_market_val = debt_market_val
|
8
|
+
@cost_of_equity = cost_of_equity
|
9
|
+
@after_tax_cost_of_debt = after_tax_cost_of_debt
|
10
|
+
|
11
|
+
e_weight = @equity_market_val / (@equity_market_val + @debt_market_val)
|
12
|
+
d_weight = @debt_market_val / (@equity_market_val + @debt_market_val)
|
13
|
+
|
14
|
+
@rate = Rate.new((e_weight * @cost_of_equity.value) + (d_weight * @after_tax_cost_of_debt.value))
|
15
|
+
end
|
16
|
+
|
17
|
+
def summary
|
18
|
+
s = CalculationSummary.new
|
19
|
+
s.title = "Cost of Capital"
|
20
|
+
s.totals_row_enabled = false
|
21
|
+
|
22
|
+
s.header_row = CalculationHeader.new(:key => "", :vals => [Date.today.to_s])
|
23
|
+
|
24
|
+
s.rows = [ ]
|
25
|
+
|
26
|
+
s.rows << CalculationRow.new(:key => "Market Value of Equity ($MM)", :vals => [@equity_market_val.to_nearest_million])
|
27
|
+
s.rows << CalculationRow.new(:key => "Market Value of Debt ($MM)", :vals => [@debt_market_val.to_nearest_million])
|
28
|
+
s.rows << CalculationRow.new(:key => "Cost of Equity (%)", :vals => [sprintf("%.2f", 100.0*@cost_of_equity.value)])
|
29
|
+
s.rows << CalculationRow.new(:key => "Cost of Debt (%)", :vals => [sprintf("%.2f", 100.0*@after_tax_cost_of_debt.value)])
|
30
|
+
s.rows << CalculationRow.new(:key => "Weighted Avg Cost of Capital (%)", :vals => [sprintf("%.2f", 100.0*@rate.value)])
|
31
|
+
|
32
|
+
return s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module YahooFinance
|
2
|
+
def YahooFinance.get_market_cap(stock_symbol)
|
3
|
+
quote = YahooFinance::get_quotes(YahooFinance::ExtendedQuote, stock_symbol).values.first
|
4
|
+
m = /([0-9\.]*)([MB])/.match(quote.marketCap)
|
5
|
+
mkt_cap = m[1].to_f
|
6
|
+
case
|
7
|
+
when m[2]=="M"
|
8
|
+
mkt_cap *= 1000*1000
|
9
|
+
when m[2]=="B"
|
10
|
+
mkt_cap *= 1000*1000*1000
|
11
|
+
end
|
12
|
+
mkt_cap
|
13
|
+
end
|
14
|
+
|
15
|
+
def YahooFinance.get_num_shares(stock_symbol)
|
16
|
+
mkt_cap = YahooFinance.get_market_cap(stock_symbol)
|
17
|
+
share_price = YahooFinance::get_quotes(YahooFinance::StandardQuote, stock_symbol).values.last.lastTrade.to_f
|
18
|
+
mkt_cap / share_price
|
19
|
+
end
|
20
|
+
end
|
data/lib/finmodeling.rb
CHANGED
@@ -1,14 +1,21 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'digest'
|
3
|
+
|
3
4
|
require 'sec_query'
|
4
5
|
require 'edgar'
|
6
|
+
require 'yahoofinance'
|
7
|
+
require 'finmodeling/yahoo_finance_helpers.rb'
|
8
|
+
require 'nasdaq_query'
|
5
9
|
|
6
10
|
require 'xbrlware-ruby19'
|
7
11
|
require 'xbrlware-extras'
|
8
12
|
|
13
|
+
require 'gsl'
|
9
14
|
require 'naive_bayes'
|
10
15
|
require 'statsample'
|
11
16
|
|
17
|
+
require 'finmodeling/invalid_filing_error'
|
18
|
+
|
12
19
|
require 'finmodeling/float_helpers'
|
13
20
|
require 'finmodeling/string_helpers'
|
14
21
|
require 'finmodeling/factory'
|
@@ -39,22 +46,41 @@ require 'finmodeling/assets_item'
|
|
39
46
|
require 'finmodeling/liabs_and_equity_item_vectors'
|
40
47
|
require 'finmodeling/liabs_and_equity_item'
|
41
48
|
require 'finmodeling/income_statement_item_vectors'
|
49
|
+
require 'finmodeling/comprehensive_income_statement_item_vectors'
|
42
50
|
require 'finmodeling/income_statement_item'
|
51
|
+
require 'finmodeling/comprehensive_income_statement_item'
|
43
52
|
require 'finmodeling/cash_change_item_vectors'
|
44
53
|
require 'finmodeling/cash_change_item'
|
54
|
+
require 'finmodeling/equity_change_item_vectors'
|
55
|
+
require 'finmodeling/equity_change_item'
|
45
56
|
|
46
57
|
require 'finmodeling/company_filing_calculation'
|
58
|
+
require 'finmodeling/can_choose_successive_periods'
|
47
59
|
require 'finmodeling/balance_sheet_calculation'
|
48
60
|
require 'finmodeling/assets_calculation'
|
49
61
|
require 'finmodeling/liabs_and_equity_calculation'
|
50
62
|
require 'finmodeling/income_statement_calculation'
|
63
|
+
require 'finmodeling/comprehensive_income_statement_calculation'
|
51
64
|
require 'finmodeling/net_income_calculation'
|
65
|
+
require 'finmodeling/comprehensive_income_calculation'
|
52
66
|
require 'finmodeling/cash_flow_statement_calculation'
|
53
67
|
require 'finmodeling/cash_change_calculation'
|
68
|
+
require 'finmodeling/shareholder_equity_statement_calculation'
|
69
|
+
require 'finmodeling/equity_change_calculation'
|
70
|
+
|
71
|
+
require 'finmodeling/net_income_summary_from_differences'
|
72
|
+
require 'finmodeling/cash_change_summary_from_differences'
|
54
73
|
|
55
74
|
require 'finmodeling/reformulated_income_statement'
|
56
75
|
require 'finmodeling/reformulated_balance_sheet'
|
57
76
|
require 'finmodeling/reformulated_cash_flow_statement'
|
77
|
+
require 'finmodeling/reformulated_shareholder_equity_statement'
|
78
|
+
|
79
|
+
require 'finmodeling/capm'
|
80
|
+
require 'finmodeling/debt_cost_of_capital'
|
81
|
+
require 'finmodeling/weighted_avg_cost_of_capital'
|
82
|
+
require 'finmodeling/fama_french_cost_of_equity'
|
83
|
+
require 'finmodeling/reoi_valuation'
|
58
84
|
|
59
85
|
require 'finmodeling/config'
|
60
86
|
|
@@ -63,8 +89,13 @@ FinModeling::Classifiers.train
|
|
63
89
|
|
64
90
|
require 'finmodeling/balance_sheet_analyses'
|
65
91
|
require 'finmodeling/income_statement_analyses'
|
92
|
+
require 'finmodeling/cash_flow_statement_analyses'
|
93
|
+
|
94
|
+
require 'finmodeling/forecasted_reformulated_income_statement'
|
95
|
+
require 'finmodeling/forecasted_reformulated_balance_sheet'
|
66
96
|
|
67
|
-
require 'finmodeling/
|
68
|
-
require 'finmodeling/
|
97
|
+
require 'finmodeling/time_series_estimator'
|
98
|
+
require 'finmodeling/trailing_avg_forecasting_policy'
|
99
|
+
require 'finmodeling/linear_trend_forecasting_policy'
|
69
100
|
require 'finmodeling/forecasts'
|
70
101
|
|
@@ -6,63 +6,99 @@ describe FinModeling::AnnualReportFiling do
|
|
6
6
|
before(:all) do
|
7
7
|
company = FinModeling::Company.new(FinModeling::Mocks::Entity.new)
|
8
8
|
filing_url = company.annual_reports.last.link
|
9
|
-
FinModeling::Config::disable_caching
|
10
9
|
@filing = FinModeling::AnnualReportFiling.download(filing_url)
|
11
10
|
end
|
12
11
|
|
13
|
-
after(:all) do
|
14
|
-
FinModeling::Config::enable_caching
|
15
|
-
end
|
16
|
-
|
17
12
|
subject { @filing }
|
18
|
-
its(:balance_sheet)
|
19
|
-
its(:income_statement)
|
20
|
-
its(:cash_flow_statement)
|
13
|
+
its(:balance_sheet) { should be_a FinModeling::BalanceSheetCalculation }
|
14
|
+
its(:income_statement) { should be_a FinModeling::IncomeStatementCalculation }
|
15
|
+
its(:cash_flow_statement) { should be_a FinModeling::CashFlowStatementCalculation }
|
21
16
|
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
context "when the report doesn't have a comprehensive income statement" do
|
18
|
+
its(:has_a_comprehensive_income_statement?) { should be_false }
|
19
|
+
its(:comprehensive_income_statement) { should be_nil }
|
20
|
+
end
|
21
|
+
context "when the report doesn't have a statement of shareholders' equity" do
|
22
|
+
its(:has_a_shareholder_equity_statement?) { should be_false }
|
23
|
+
its(:shareholder_equity_statement) { should be_nil }
|
24
|
+
its(:is_valid?) { should == [@filing.income_statement,
|
25
|
+
@filing.balance_sheet,
|
26
|
+
@filing.cash_flow_statement].all?{|x| x.is_valid?} }
|
27
|
+
end
|
28
|
+
context "when the report has a statement of shareholders' equity" do
|
25
29
|
before(:all) do
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
filing_url = "http://www.sec.gov/Archives/edgar/data/315189/000110465910063219/0001104659-10-063219-index.htm"
|
31
|
+
FinModeling::Config::disable_caching
|
32
|
+
@filing = FinModeling::AnnualReportFiling.download filing_url
|
33
|
+
FinModeling::Config::enable_caching
|
34
|
+
end
|
35
|
+
subject { @filing }
|
32
36
|
|
33
|
-
|
37
|
+
its(:has_a_shareholder_equity_statement?) { should be_true }
|
38
|
+
its(:shareholder_equity_statement) { should be_a FinModeling::ShareholderEquityStatementCalculation }
|
39
|
+
its(:is_valid?) { should == [@filing.income_statement,
|
40
|
+
@filing.balance_sheet,
|
41
|
+
@filing.cash_flow_statement,
|
42
|
+
@filing.shareholder_equity_statement].all?{|x| x.is_valid?} }
|
34
43
|
|
35
|
-
|
36
|
-
|
44
|
+
context "after write_constructor()ing it to a file and then eval()ing the results" do
|
45
|
+
before(:all) do
|
46
|
+
file_name = "/tmp/finmodeling-annual-rpt.rb"
|
47
|
+
schema_version_item_name = "@schema_version"
|
48
|
+
item_name = "@annual_rpt"
|
49
|
+
file = File.open(file_name, "w")
|
50
|
+
@filing.write_constructor(file, item_name)
|
51
|
+
file.close
|
52
|
+
|
53
|
+
eval(File.read(file_name))
|
54
|
+
|
55
|
+
@schema_version = eval(schema_version_item_name)
|
56
|
+
@loaded_filing = eval(item_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
specify { @schema_version.should be == 1.3 }
|
60
|
+
|
61
|
+
subject { @loaded_filing }
|
62
|
+
its(:balance_sheet) { should have_the_same_periods_as(@filing.balance_sheet) }
|
63
|
+
its(:balance_sheet) { should have_the_same_reformulated_last_total(:net_operating_assets).as(@filing.balance_sheet) }
|
64
|
+
its(:income_statement) { should have_the_same_reformulated_last_total(:net_financing_income).as(@filing.income_statement) }
|
65
|
+
its(:cash_flow_statement) { should have_the_same_last_total(:cash_change_calculation).as(@filing.cash_flow_statement) }
|
66
|
+
its(:shareholder_equity_statement) { should be_a FinModeling::ShareholderEquityStatementCalculation }
|
67
|
+
its(:shareholder_equity_statement) { should have_the_same_last_total(:equity_change_calculation).as(@filing.shareholder_equity_statement) }
|
68
|
+
its(:disclosures) { should have_the_same_last_total(:first).as(@filing.disclosures) }
|
37
69
|
end
|
70
|
+
end
|
38
71
|
|
39
|
-
|
40
|
-
|
72
|
+
context "when the report has a comprehensive income statement" do
|
73
|
+
before(:all) do
|
74
|
+
filing_url = "http://www.sec.gov/Archives/edgar/data/818479/000081847912000023/0000818479-12-000023-index.htm"
|
75
|
+
FinModeling::Config::disable_caching
|
76
|
+
@filing = FinModeling::AnnualReportFiling.download filing_url
|
77
|
+
FinModeling::Config::enable_caching
|
41
78
|
end
|
79
|
+
subject { @filing }
|
42
80
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
it "writes itself to a file, and when reloaded, has the same disclosures" do
|
63
|
-
period = @filing.disclosures.first.periods.last
|
64
|
-
expected_total = @filing.disclosures.first.summary(:period=>period).total
|
65
|
-
@loaded_filing.disclosures.first.summary(:period=>period).total.should == expected_total
|
81
|
+
its(:has_a_comprehensive_income_statement?) { should be_true }
|
82
|
+
its(:comprehensive_income_statement) { should be_a FinModeling::ComprehensiveIncomeStatementCalculation }
|
83
|
+
|
84
|
+
context "after write_constructor()ing it to a file and then eval()ing the results" do
|
85
|
+
before(:all) do
|
86
|
+
file_name = "/tmp/finmodeling-annual-rpt.rb"
|
87
|
+
schema_version_item_name = "@schema_version"
|
88
|
+
item_name = "@annual_rpt"
|
89
|
+
file = File.open(file_name, "w")
|
90
|
+
@filing.write_constructor(file, item_name)
|
91
|
+
file.close
|
92
|
+
|
93
|
+
eval(File.read(file_name))
|
94
|
+
@loaded_filing = eval(item_name)
|
95
|
+
end
|
96
|
+
|
97
|
+
subject { @loaded_filing }
|
98
|
+
its(:comprehensive_income_statement) { should be_a FinModeling::ComprehensiveIncomeStatementCalculation }
|
99
|
+
its(:comprehensive_income_statement) { should have_the_same_last_total(:comprehensive_income_calculation).as(@filing.comprehensive_income_statement) }
|
66
100
|
end
|
101
|
+
|
67
102
|
end
|
103
|
+
|
68
104
|
end
|
@@ -12,10 +12,13 @@ describe FinModeling::AssetsCalculation do
|
|
12
12
|
@a = @bal_sheet.assets_calculation
|
13
13
|
end
|
14
14
|
|
15
|
-
describe "summary" do
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
describe ".summary" do
|
16
|
+
subject { @a.summary(:period=>@period) }
|
17
|
+
it { should be_a FinModeling::CalculationSummary }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".has_cash_item" do
|
21
|
+
pending "Find a test case..."
|
19
22
|
end
|
20
23
|
end
|
21
24
|
|
data/spec/assets_item_spec.rb
CHANGED
@@ -9,33 +9,28 @@ describe FinModeling::AssetsItem do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
describe "new" do
|
12
|
-
|
13
|
-
|
14
|
-
ai.should be_an_instance_of FinModeling::AssetsItem
|
15
|
-
end
|
12
|
+
subject { FinModeling::AssetsItem.new("Property Plant And Equipment Net") }
|
13
|
+
it { should be_a FinModeling::AssetsItem }
|
16
14
|
end
|
17
15
|
|
18
16
|
describe "train" do
|
17
|
+
subject { FinModeling::AssetsItem.new("Property Plant And Equipment Net") }
|
19
18
|
it "trains the classifier that this AssetsItem is of the given type" do
|
20
|
-
|
19
|
+
subject.train(:oa)
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
23
|
describe "classification_estimates" do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
FinModeling::AssetsItem::TYPES.each do |klass|
|
29
|
-
ai.classification_estimates.keys.include?(klass).should be_true
|
30
|
-
end
|
31
|
-
end
|
24
|
+
subject { FinModeling::AssetsItem.new("Property Plant And Equipment Net").classification_estimates }
|
25
|
+
its(:keys) { should == FinModeling::AssetsItem::TYPES }
|
32
26
|
end
|
33
27
|
|
34
28
|
describe "classify" do
|
29
|
+
let(:ai) { FinModeling::AssetsItem.new("Property Plant And Equipment Net") }
|
30
|
+
subject { ai.classify }
|
35
31
|
it "returns the AssetsItem type with the highest probability estimate" do
|
36
|
-
ai = FinModeling::AssetsItem.new("Property Plant And Equipment Net")
|
37
32
|
estimates = ai.classification_estimates
|
38
|
-
estimates[
|
33
|
+
estimates[subject].should be_within(0.1).of(estimates.values.max)
|
39
34
|
end
|
40
35
|
end
|
41
36
|
|
@@ -8,30 +8,30 @@ describe FinModeling::BalanceSheetAnalyses do
|
|
8
8
|
@summary.title = "Title 123"
|
9
9
|
@summary.rows = [ ]
|
10
10
|
@summary.rows << FinModeling::CalculationRow.new(:key => "NOA Growth", :type => :oa, :vals => [ 4])
|
11
|
-
@summary.rows << FinModeling::CalculationRow.new(:key => "Row",
|
12
|
-
@summary.rows << FinModeling::CalculationRow.new(:key => "Row",
|
13
|
-
@summary.rows << FinModeling::CalculationRow.new(:key => "Row",
|
11
|
+
@summary.rows << FinModeling::CalculationRow.new(:key => "Row", :type => :fa, :vals => [109])
|
12
|
+
@summary.rows << FinModeling::CalculationRow.new(:key => "Row", :type => :oa, :vals => [ 93])
|
13
|
+
@summary.rows << FinModeling::CalculationRow.new(:key => "Row", :type => :fa, :vals => [ 1])
|
14
14
|
end
|
15
15
|
|
16
16
|
describe ".new" do
|
17
17
|
subject { FinModeling::BalanceSheetAnalyses.new(@summary) }
|
18
18
|
|
19
19
|
it { should be_a_kind_of FinModeling::CalculationSummary }
|
20
|
-
its(:title)
|
21
|
-
its(:rows)
|
22
|
-
its(:header_row)
|
23
|
-
its(:rows)
|
24
|
-
its(:num_value_columns)
|
25
|
-
its(:key_width)
|
26
|
-
its(:val_width)
|
27
|
-
its(:max_decimals)
|
20
|
+
its(:title) { should == @summary.title }
|
21
|
+
its(:rows) { should == @summary.rows }
|
22
|
+
its(:header_row) { should == @summary.header_row }
|
23
|
+
its(:rows) { should == @summary.rows }
|
24
|
+
its(:num_value_columns) { should == @summary.num_value_columns }
|
25
|
+
its(:key_width) { should == @summary.key_width }
|
26
|
+
its(:val_width) { should == @summary.val_width }
|
27
|
+
its(:max_decimals) { should == @summary.max_decimals }
|
28
28
|
its(:totals_row_enabled) { should be_false }
|
29
29
|
end
|
30
30
|
|
31
|
-
describe ".
|
31
|
+
describe ".print_regressions" do
|
32
32
|
subject { FinModeling::BalanceSheetAnalyses.new(@summary) }
|
33
33
|
|
34
|
-
it { should respond_to(:
|
34
|
+
it { should respond_to(:print_regressions) }
|
35
35
|
end
|
36
36
|
|
37
37
|
describe ".noa_growth_row" do
|
@@ -10,60 +10,59 @@ describe FinModeling::BalanceSheetCalculation do
|
|
10
10
|
@period = @balance_sheet.periods.last
|
11
11
|
end
|
12
12
|
|
13
|
-
describe "assets_calculation" do
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
it "sums to the same value as do the liabilities and equity" do
|
21
|
-
left_sum = @balance_sheet.assets_calculation.leaf_items_sum(:period=>@period)
|
22
|
-
right_sum = @balance_sheet.liabs_and_equity_calculation.leaf_items_sum(:period=>@period)
|
23
|
-
left_sum.should be_within(1.0).of(right_sum)
|
24
|
-
end
|
13
|
+
describe ".assets_calculation" do
|
14
|
+
subject { @balance_sheet.assets_calculation }
|
15
|
+
it { should be_a FinModeling::AssetsCalculation }
|
16
|
+
its(:label) { should match /asset/i }
|
17
|
+
|
18
|
+
let(:right_side_sum) { @balance_sheet.liabs_and_equity_calculation.leaf_items_sum(:period=>@period) }
|
19
|
+
specify { subject.leaf_items_sum(:period=>@period).should be_within(1.0).of(right_side_sum) }
|
25
20
|
end
|
26
21
|
|
27
|
-
describe "liabs_and_equity_calculation" do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
it "returns the root node of the liability & shareholders' equity calculation" do
|
32
|
-
@balance_sheet.liabs_and_equity_calculation.label.downcase.should match /liab.*equity/
|
33
|
-
end
|
22
|
+
describe ".liabs_and_equity_calculation" do
|
23
|
+
subject { @balance_sheet.liabs_and_equity_calculation}
|
24
|
+
it { should be_a FinModeling::LiabsAndEquityCalculation }
|
25
|
+
its(:label) { should match /liab.*equity/i }
|
34
26
|
end
|
35
27
|
|
36
|
-
describe "is_valid?" do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
describe ".is_valid?" do
|
29
|
+
context "if none of the asset leaf nodes contains the term 'cash'" do
|
30
|
+
it "returns false" do
|
31
|
+
#ea_2011_annual_rpt = "http://www.sec.gov/Archives/edgar/data/712515/000119312511149262/0001193125-11-149262-index.htm"
|
32
|
+
#filing = FinModeling::AnnualReportFiling.download ea_2011_annual_rpt
|
33
|
+
#filing.balance_sheet.is_valid?.should be_false
|
34
|
+
pending "Need to find another example of this...."
|
35
|
+
end
|
42
36
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
context "if none of the liability/equity net income leaf nodes contains the term 'equity'" do
|
38
|
+
it "returns false" do
|
39
|
+
#ea_2011_annual_rpt = "http://www.sec.gov/Archives/edgar/data/712515/000119312511149262/0001193125-11-149262-index.htm"
|
40
|
+
#filing = FinModeling::AnnualReportFiling.download ea_2011_annual_rpt
|
41
|
+
#filing.balance_sheet.is_valid?.should be_false
|
42
|
+
pending "Need to find another example of this...."
|
43
|
+
end
|
48
44
|
end
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
45
|
+
context "if the assets total does not match the liabilities and equity total" do
|
46
|
+
it "returns false" do
|
47
|
+
#ea_2011_annual_rpt = "http://www.sec.gov/Archives/edgar/data/712515/000119312511149262/0001193125-11-149262-index.htm"
|
48
|
+
#filing = FinModeling::AnnualReportFiling.download ea_2011_annual_rpt
|
49
|
+
#filing.balance_sheet.is_valid?.should be_false
|
50
|
+
pending "Need to find another example of this...."
|
51
|
+
end
|
54
52
|
end
|
55
|
-
|
56
|
-
|
53
|
+
context "otherwise" do
|
54
|
+
it "returns true" do
|
55
|
+
@balance_sheet.is_valid?.should be_true
|
56
|
+
end
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
describe "reformulated" do
|
61
|
-
|
62
|
-
|
63
|
-
end
|
60
|
+
describe ".reformulated" do
|
61
|
+
subject { @balance_sheet.reformulated(@period) }
|
62
|
+
it { should be_a FinModeling::ReformulatedBalanceSheet }
|
64
63
|
end
|
65
64
|
|
66
|
-
describe "write_constructor" do
|
65
|
+
describe ".write_constructor" do
|
67
66
|
before(:all) do
|
68
67
|
file_name = "/tmp/finmodeling-bal-sheet.rb"
|
69
68
|
item_name = "@bal_sheet"
|
@@ -72,18 +71,13 @@ describe FinModeling::BalanceSheetCalculation do
|
|
72
71
|
file.close
|
73
72
|
|
74
73
|
eval(File.read(file_name))
|
75
|
-
|
76
74
|
@loaded_bs = eval(item_name)
|
77
75
|
end
|
78
76
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
it "writes itself to a file, and when reloaded, has the same net operating assets" do
|
84
|
-
period = @balance_sheet.periods.last
|
85
|
-
expected_noa = @balance_sheet.reformulated(period).net_operating_assets.total
|
86
|
-
@loaded_bs.reformulated(period).net_operating_assets.total.should be_within(1.0).of(expected_noa)
|
77
|
+
context "after write_constructor()ing it to a file and then eval()ing the results" do
|
78
|
+
subject { @loaded_bs }
|
79
|
+
it { should have_the_same_periods_as @balance_sheet }
|
80
|
+
it { should have_the_same_reformulated_last_total(:net_operating_assets).as(@balance_sheet) }
|
87
81
|
end
|
88
82
|
end
|
89
83
|
|