eodhd.rb 0.18.1 → 0.19.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +25 -0
- data/lib/Eodhd/Fundamentals/Earnings/AnnualEntry.rb +21 -0
- data/lib/Eodhd/Fundamentals/Earnings/HistoryEntry.rb +33 -0
- data/lib/Eodhd/Fundamentals/Earnings/TrendEntry.rb +65 -0
- data/lib/Eodhd/Fundamentals/Earnings.rb +12 -3
- data/lib/Eodhd/Fundamentals/Financials/BalanceSheet/Entry.rb +147 -0
- data/lib/Eodhd/Fundamentals/Financials/BalanceSheet.rb +28 -0
- data/lib/Eodhd/Fundamentals/Financials/CashFlow/Entry.rb +83 -0
- data/lib/Eodhd/Fundamentals/Financials/CashFlow.rb +28 -0
- data/lib/Eodhd/Fundamentals/Financials/IncomeStatement/Entry.rb +87 -0
- data/lib/Eodhd/Fundamentals/Financials/IncomeStatement.rb +28 -0
- data/lib/Eodhd/Fundamentals/Financials.rb +6 -4
- data/lib/Eodhd/Fundamentals/Holders/Fund.rb +31 -0
- data/lib/Eodhd/Fundamentals/Holders/Institution.rb +31 -0
- data/lib/Eodhd/Fundamentals/Holders.rb +10 -2
- data/lib/Eodhd/Fundamentals/InsiderTransaction.rb +35 -0
- data/lib/Eodhd/Fundamentals/OutstandingShares/Entry.rb +25 -0
- data/lib/Eodhd/Fundamentals/OutstandingShares.rb +26 -0
- data/lib/Eodhd/Fundamentals.rb +9 -2
- data/lib/Eodhd/VERSION.rb +1 -1
- data/test/Eodhd/Fundamentals_test.rb +92 -7
- metadata +16 -3
- data/lib/Eodhd/Fundamentals/Financials/Statement.rb +0 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e347f01c6ec9787d6a54688677b37264b7d69eeffcd1e074c1fd13ae87cb4cb5
|
|
4
|
+
data.tar.gz: 7a75d41121973122134371a0a860736c0ce9648b06bf61d9c98f359fc71fe590
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1bf08b3757f5f6e6425c4af75475aab51ed62914040389f522a01547c2e4f68b3ef09a74d0000729742545aecfca7c0e04d01121f2d0f61b5e666dee9997a03e
|
|
7
|
+
data.tar.gz: 2532629e1aa4fbb1c22cf35794b506a682b8b616f43e59746f0ee23fd2a38c77693313c61999dc072376690fa7b70c6fb43c7c1dcf128a0556d53691116af7eb
|
data/CHANGELOG
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# eodhd.rb/CHANGELOG
|
|
2
2
|
|
|
3
|
+
## [0.19.0] - 2026-07-19, complete the fundamentals model wrapping
|
|
4
|
+
- + Eodhd::Fundamentals::Financials::BalanceSheet::Entry: Typed entry for a balance sheet period (64 fields).
|
|
5
|
+
- + Eodhd::Fundamentals::Financials::IncomeStatement::Entry: Typed entry for an income statement period (34 fields).
|
|
6
|
+
- + Eodhd::Fundamentals::Financials::CashFlow::Entry: Typed entry for a cash flow period (32 fields).
|
|
7
|
+
- + Eodhd::Fundamentals::Earnings::AnnualEntry
|
|
8
|
+
- + Eodhd::Fundamentals::Earnings::HistoryEntry
|
|
9
|
+
- + Eodhd::Fundamentals::Earnings::TrendEntry
|
|
10
|
+
- + Eodhd::Fundamentals::Holders::Institution: Typed entry for an institutional holder.
|
|
11
|
+
- + Eodhd::Fundamentals::Holders::Fund: Typed entry for a fund holder.
|
|
12
|
+
- + Eodhd::Fundamentals::InsiderTransaction: Typed entry for an insider transaction.
|
|
13
|
+
- + Eodhd::Fundamentals::OutstandingShares::Entry: Typed entry for an outstanding shares data point.
|
|
14
|
+
- + Eodhd::Fundamentals::OutstandingShares: Wraps annual and quarterly OutstandingShares::Entry arrays.
|
|
15
|
+
- + Eodhd::Fundamentals::Financials::BalanceSheet
|
|
16
|
+
- + Eodhd::Fundamentals::Financials::IncomeStatement
|
|
17
|
+
- + Eodhd::Fundamentals::Financials::CashFlow
|
|
18
|
+
- ~ Eodhd::Fundamentals::Financials: Build BalanceSheet/IncomeStatement/CashFlow instead of the shared Statement.
|
|
19
|
+
- ~ Eodhd::Fundamentals::Financials::BalanceSheet#yearly, #quarterly: Now sorted arrays of typed entries, was raw hashes.
|
|
20
|
+
- ~ Eodhd::Fundamentals::Earnings#annual, #history, #trend: Now sorted arrays of typed entries, was raw hashes.
|
|
21
|
+
- ~ Eodhd::Fundamentals::Holders#institutions, #funds: Now arrays of typed entries, was raw hashes.
|
|
22
|
+
- ~ Eodhd::Fundamentals#insider_transactions: Now a sorted array of InsiderTransaction, was a raw hash.
|
|
23
|
+
- ~ Eodhd::Fundamentals#outstanding_shares: Now an OutstandingShares object, was a raw hash.
|
|
24
|
+
- + test/Eodhd/Fundamentals_test.rb: Cover the newly wrapped entry types and collections.
|
|
25
|
+
- - Eodhd::Fundamentals::Financials::Statement: Replaced by the three per-statement classes.
|
|
26
|
+
- ~ Eodhd/VERSION: /0.18.1/0.19.0/
|
|
27
|
+
|
|
3
28
|
## [0.18.1] - 2026-07-19, urlencode helper naming consistency
|
|
4
29
|
- /Thoran::String::UrlEncode#url_encode/Thoran::String::Urlencode#urlencode/ (url_encode kept as an alias).
|
|
5
30
|
- /Thoran::Hash::XWwwFormUrlEncode#x_www_form_url_encode/Thoran::Hash::XWwwFormUrlencode#x_www_form_urlencode/ (x_www_form_url_encode kept as an alias).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Earnings/AnnualEntry.rb
|
|
2
|
+
# Eodhd::Fundamentals::Earnings::AnnualEntry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Earnings
|
|
7
|
+
class AnnualEntry
|
|
8
|
+
attr_reader\
|
|
9
|
+
:date,
|
|
10
|
+
:eps_actual
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def initialize(data)
|
|
15
|
+
@date = data['date']
|
|
16
|
+
@eps_actual = data['epsActual']
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Earnings/HistoryEntry.rb
|
|
2
|
+
# Eodhd::Fundamentals::Earnings::HistoryEntry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Earnings
|
|
7
|
+
class HistoryEntry
|
|
8
|
+
attr_reader\
|
|
9
|
+
:report_date,
|
|
10
|
+
:date,
|
|
11
|
+
:before_after_market,
|
|
12
|
+
:currency,
|
|
13
|
+
:eps_actual,
|
|
14
|
+
:eps_estimate,
|
|
15
|
+
:eps_difference,
|
|
16
|
+
:surprise_percent
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def initialize(data)
|
|
21
|
+
@report_date = data['reportDate']
|
|
22
|
+
@date = data['date']
|
|
23
|
+
@before_after_market = data['beforeAfterMarket']
|
|
24
|
+
@currency = data['currency']
|
|
25
|
+
@eps_actual = data['epsActual']
|
|
26
|
+
@eps_estimate = data['epsEstimate']
|
|
27
|
+
@eps_difference = data['epsDifference']
|
|
28
|
+
@surprise_percent = data['surprisePercent']
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Earnings/TrendEntry.rb
|
|
2
|
+
# Eodhd::Fundamentals::Earnings::TrendEntry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Earnings
|
|
7
|
+
class TrendEntry
|
|
8
|
+
attr_reader\
|
|
9
|
+
:date,
|
|
10
|
+
:period,
|
|
11
|
+
:growth,
|
|
12
|
+
:earnings_estimate_avg,
|
|
13
|
+
:earnings_estimate_low,
|
|
14
|
+
:earnings_estimate_high,
|
|
15
|
+
:earnings_estimate_year_ago_eps,
|
|
16
|
+
:earnings_estimate_number_of_analysts,
|
|
17
|
+
:earnings_estimate_growth,
|
|
18
|
+
:revenue_estimate_avg,
|
|
19
|
+
:revenue_estimate_low,
|
|
20
|
+
:revenue_estimate_high,
|
|
21
|
+
:revenue_estimate_year_ago_eps,
|
|
22
|
+
:revenue_estimate_number_of_analysts,
|
|
23
|
+
:revenue_estimate_growth,
|
|
24
|
+
:eps_trend_current,
|
|
25
|
+
:eps_trend_7_days_ago,
|
|
26
|
+
:eps_trend_30_days_ago,
|
|
27
|
+
:eps_trend_60_days_ago,
|
|
28
|
+
:eps_trend_90_days_ago,
|
|
29
|
+
:eps_revisions_up_last_7_days,
|
|
30
|
+
:eps_revisions_up_last_30_days,
|
|
31
|
+
:eps_revisions_down_last_7_days,
|
|
32
|
+
:eps_revisions_down_last_30_days
|
|
33
|
+
|
|
34
|
+
private
|
|
35
|
+
|
|
36
|
+
def initialize(data)
|
|
37
|
+
@date = data['date']
|
|
38
|
+
@period = data['period']
|
|
39
|
+
@growth = data['growth']
|
|
40
|
+
@earnings_estimate_avg = data['earningsEstimateAvg']
|
|
41
|
+
@earnings_estimate_low = data['earningsEstimateLow']
|
|
42
|
+
@earnings_estimate_high = data['earningsEstimateHigh']
|
|
43
|
+
@earnings_estimate_year_ago_eps = data['earningsEstimateYearAgoEps']
|
|
44
|
+
@earnings_estimate_number_of_analysts = data['earningsEstimateNumberOfAnalysts']
|
|
45
|
+
@earnings_estimate_growth = data['earningsEstimateGrowth']
|
|
46
|
+
@revenue_estimate_avg = data['revenueEstimateAvg']
|
|
47
|
+
@revenue_estimate_low = data['revenueEstimateLow']
|
|
48
|
+
@revenue_estimate_high = data['revenueEstimateHigh']
|
|
49
|
+
@revenue_estimate_year_ago_eps = data['revenueEstimateYearAgoEps']
|
|
50
|
+
@revenue_estimate_number_of_analysts = data['revenueEstimateNumberOfAnalysts']
|
|
51
|
+
@revenue_estimate_growth = data['revenueEstimateGrowth']
|
|
52
|
+
@eps_trend_current = data['epsTrendCurrent']
|
|
53
|
+
@eps_trend_7_days_ago = data['epsTrend7daysAgo']
|
|
54
|
+
@eps_trend_30_days_ago = data['epsTrend30daysAgo']
|
|
55
|
+
@eps_trend_60_days_ago = data['epsTrend60daysAgo']
|
|
56
|
+
@eps_trend_90_days_ago = data['epsTrend90daysAgo']
|
|
57
|
+
@eps_revisions_up_last_7_days = data['epsRevisionsUpLast7days']
|
|
58
|
+
@eps_revisions_up_last_30_days = data['epsRevisionsUpLast30days']
|
|
59
|
+
@eps_revisions_down_last_7_days = data['epsRevisionsDownLast7days']
|
|
60
|
+
@eps_revisions_down_last_30_days = data['epsRevisionsDownLast30days']
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Eodhd/Fundamentals/Earnings.rb
|
|
2
2
|
# Eodhd::Fundamentals::Earnings
|
|
3
3
|
|
|
4
|
+
require_relative './Earnings/AnnualEntry'
|
|
5
|
+
require_relative './Earnings/HistoryEntry'
|
|
6
|
+
require_relative './Earnings/TrendEntry'
|
|
7
|
+
|
|
4
8
|
class Eodhd
|
|
5
9
|
class Fundamentals
|
|
6
10
|
class Earnings
|
|
@@ -12,9 +16,14 @@ class Eodhd
|
|
|
12
16
|
private
|
|
13
17
|
|
|
14
18
|
def initialize(data)
|
|
15
|
-
@
|
|
16
|
-
@
|
|
17
|
-
@
|
|
19
|
+
@annual = wrap(data['Annual'], AnnualEntry)
|
|
20
|
+
@history = wrap(data['History'], HistoryEntry)
|
|
21
|
+
@trend = wrap(data['Trend'], TrendEntry)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def wrap(entries, entry_class)
|
|
25
|
+
return [] unless entries
|
|
26
|
+
entries.values.map{|entry| entry_class.new(entry)}.sort_by(&:date)
|
|
18
27
|
end
|
|
19
28
|
end
|
|
20
29
|
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Financials/BalanceSheet/Entry.rb
|
|
2
|
+
# Eodhd::Fundamentals::Financials::BalanceSheet::Entry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Financials
|
|
7
|
+
class BalanceSheet
|
|
8
|
+
class Entry
|
|
9
|
+
attr_reader\
|
|
10
|
+
:date,
|
|
11
|
+
:filing_date,
|
|
12
|
+
:currency_symbol,
|
|
13
|
+
:total_assets,
|
|
14
|
+
:intangible_assets,
|
|
15
|
+
:earning_assets,
|
|
16
|
+
:other_current_assets,
|
|
17
|
+
:total_liabilities,
|
|
18
|
+
:total_stockholder_equity,
|
|
19
|
+
:deferred_long_term_liabilities,
|
|
20
|
+
:other_current_liabilities,
|
|
21
|
+
:common_stock,
|
|
22
|
+
:capital_stock,
|
|
23
|
+
:retained_earnings,
|
|
24
|
+
:other_liabilities,
|
|
25
|
+
:goodwill,
|
|
26
|
+
:other_assets,
|
|
27
|
+
:cash,
|
|
28
|
+
:cash_and_equivalents,
|
|
29
|
+
:total_current_liabilities,
|
|
30
|
+
:current_deferred_revenue,
|
|
31
|
+
:net_debt,
|
|
32
|
+
:short_term_debt,
|
|
33
|
+
:short_long_term_debt,
|
|
34
|
+
:short_long_term_debt_total,
|
|
35
|
+
:other_stockholder_equity,
|
|
36
|
+
:property_plant_equipment,
|
|
37
|
+
:total_current_assets,
|
|
38
|
+
:long_term_investments,
|
|
39
|
+
:net_tangible_assets,
|
|
40
|
+
:short_term_investments,
|
|
41
|
+
:net_receivables,
|
|
42
|
+
:long_term_debt,
|
|
43
|
+
:inventory,
|
|
44
|
+
:accounts_payable,
|
|
45
|
+
:total_permanent_equity,
|
|
46
|
+
:noncontrolling_interest_in_consolidated_entity,
|
|
47
|
+
:temporary_equity_redeemable_noncontrolling_interests,
|
|
48
|
+
:accumulated_other_comprehensive_income,
|
|
49
|
+
:additional_paid_in_capital,
|
|
50
|
+
:common_stock_total_equity,
|
|
51
|
+
:preferred_stock_total_equity,
|
|
52
|
+
:retained_earnings_total_equity,
|
|
53
|
+
:treasury_stock,
|
|
54
|
+
:accumulated_amortization,
|
|
55
|
+
:non_current_assets_other,
|
|
56
|
+
:deferred_long_term_asset_charges,
|
|
57
|
+
:non_current_assets_total,
|
|
58
|
+
:capital_lease_obligations,
|
|
59
|
+
:long_term_debt_total,
|
|
60
|
+
:non_current_liabilities_other,
|
|
61
|
+
:non_current_liabilities_total,
|
|
62
|
+
:negative_goodwill,
|
|
63
|
+
:warrants,
|
|
64
|
+
:preferred_stock_redeemable,
|
|
65
|
+
:capital_surplus,
|
|
66
|
+
:liabilities_and_stockholders_equity,
|
|
67
|
+
:cash_and_short_term_investments,
|
|
68
|
+
:property_plant_and_equipment_gross,
|
|
69
|
+
:property_plant_and_equipment_net,
|
|
70
|
+
:accumulated_depreciation,
|
|
71
|
+
:net_working_capital,
|
|
72
|
+
:net_invested_capital,
|
|
73
|
+
:common_stock_shares_outstanding
|
|
74
|
+
|
|
75
|
+
private
|
|
76
|
+
|
|
77
|
+
def initialize(data)
|
|
78
|
+
@date = data['date']
|
|
79
|
+
@filing_date = data['filing_date']
|
|
80
|
+
@currency_symbol = data['currency_symbol']
|
|
81
|
+
@total_assets = data['totalAssets']
|
|
82
|
+
@intangible_assets = data['intangibleAssets']
|
|
83
|
+
@earning_assets = data['earningAssets']
|
|
84
|
+
@other_current_assets = data['otherCurrentAssets']
|
|
85
|
+
@total_liabilities = data['totalLiab']
|
|
86
|
+
@total_stockholder_equity = data['totalStockholderEquity']
|
|
87
|
+
@deferred_long_term_liabilities = data['deferredLongTermLiab']
|
|
88
|
+
@other_current_liabilities = data['otherCurrentLiab']
|
|
89
|
+
@common_stock = data['commonStock']
|
|
90
|
+
@capital_stock = data['capitalStock']
|
|
91
|
+
@retained_earnings = data['retainedEarnings']
|
|
92
|
+
@other_liabilities = data['otherLiab']
|
|
93
|
+
@goodwill = data['goodWill']
|
|
94
|
+
@other_assets = data['otherAssets']
|
|
95
|
+
@cash = data['cash']
|
|
96
|
+
@cash_and_equivalents = data['cashAndEquivalents']
|
|
97
|
+
@total_current_liabilities = data['totalCurrentLiabilities']
|
|
98
|
+
@current_deferred_revenue = data['currentDeferredRevenue']
|
|
99
|
+
@net_debt = data['netDebt']
|
|
100
|
+
@short_term_debt = data['shortTermDebt']
|
|
101
|
+
@short_long_term_debt = data['shortLongTermDebt']
|
|
102
|
+
@short_long_term_debt_total = data['shortLongTermDebtTotal']
|
|
103
|
+
@other_stockholder_equity = data['otherStockholderEquity']
|
|
104
|
+
@property_plant_equipment = data['propertyPlantEquipment']
|
|
105
|
+
@total_current_assets = data['totalCurrentAssets']
|
|
106
|
+
@long_term_investments = data['longTermInvestments']
|
|
107
|
+
@net_tangible_assets = data['netTangibleAssets']
|
|
108
|
+
@short_term_investments = data['shortTermInvestments']
|
|
109
|
+
@net_receivables = data['netReceivables']
|
|
110
|
+
@long_term_debt = data['longTermDebt']
|
|
111
|
+
@inventory = data['inventory']
|
|
112
|
+
@accounts_payable = data['accountsPayable']
|
|
113
|
+
@total_permanent_equity = data['totalPermanentEquity']
|
|
114
|
+
@noncontrolling_interest_in_consolidated_entity = data['noncontrollingInterestInConsolidatedEntity']
|
|
115
|
+
@temporary_equity_redeemable_noncontrolling_interests = data['temporaryEquityRedeemableNoncontrollingInterests']
|
|
116
|
+
@accumulated_other_comprehensive_income = data['accumulatedOtherComprehensiveIncome']
|
|
117
|
+
@additional_paid_in_capital = data['additionalPaidInCapital']
|
|
118
|
+
@common_stock_total_equity = data['commonStockTotalEquity']
|
|
119
|
+
@preferred_stock_total_equity = data['preferredStockTotalEquity']
|
|
120
|
+
@retained_earnings_total_equity = data['retainedEarningsTotalEquity']
|
|
121
|
+
@treasury_stock = data['treasuryStock']
|
|
122
|
+
@accumulated_amortization = data['accumulatedAmortization']
|
|
123
|
+
@non_current_assets_other = data['nonCurrrentAssetsOther']
|
|
124
|
+
@deferred_long_term_asset_charges = data['deferredLongTermAssetCharges']
|
|
125
|
+
@non_current_assets_total = data['nonCurrentAssetsTotal']
|
|
126
|
+
@capital_lease_obligations = data['capitalLeaseObligations']
|
|
127
|
+
@long_term_debt_total = data['longTermDebtTotal']
|
|
128
|
+
@non_current_liabilities_other = data['nonCurrentLiabilitiesOther']
|
|
129
|
+
@non_current_liabilities_total = data['nonCurrentLiabilitiesTotal']
|
|
130
|
+
@negative_goodwill = data['negativeGoodwill']
|
|
131
|
+
@warrants = data['warrants']
|
|
132
|
+
@preferred_stock_redeemable = data['preferredStockRedeemable']
|
|
133
|
+
@capital_surplus = data['capitalSurpluse']
|
|
134
|
+
@liabilities_and_stockholders_equity = data['liabilitiesAndStockholdersEquity']
|
|
135
|
+
@cash_and_short_term_investments = data['cashAndShortTermInvestments']
|
|
136
|
+
@property_plant_and_equipment_gross = data['propertyPlantAndEquipmentGross']
|
|
137
|
+
@property_plant_and_equipment_net = data['propertyPlantAndEquipmentNet']
|
|
138
|
+
@accumulated_depreciation = data['accumulatedDepreciation']
|
|
139
|
+
@net_working_capital = data['netWorkingCapital']
|
|
140
|
+
@net_invested_capital = data['netInvestedCapital']
|
|
141
|
+
@common_stock_shares_outstanding = data['commonStockSharesOutstanding']
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Financials/BalanceSheet.rb
|
|
2
|
+
# Eodhd::Fundamentals::Financials::BalanceSheet
|
|
3
|
+
|
|
4
|
+
require_relative './BalanceSheet/Entry'
|
|
5
|
+
|
|
6
|
+
class Eodhd
|
|
7
|
+
class Fundamentals
|
|
8
|
+
class Financials
|
|
9
|
+
class BalanceSheet
|
|
10
|
+
attr_reader\
|
|
11
|
+
:quarterly,
|
|
12
|
+
:yearly
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def initialize(data)
|
|
17
|
+
@yearly = wrap(data['yearly'])
|
|
18
|
+
@quarterly = wrap(data['quarterly'])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def wrap(entries)
|
|
22
|
+
return [] unless entries
|
|
23
|
+
entries.values.map{|entry| Entry.new(entry)}.sort_by(&:date)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Financials/CashFlow/Entry.rb
|
|
2
|
+
# Eodhd::Fundamentals::Financials::CashFlow::Entry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Financials
|
|
7
|
+
class CashFlow
|
|
8
|
+
class Entry
|
|
9
|
+
attr_reader\
|
|
10
|
+
:date,
|
|
11
|
+
:filing_date,
|
|
12
|
+
:currency_symbol,
|
|
13
|
+
:investments,
|
|
14
|
+
:change_to_liabilities,
|
|
15
|
+
:total_cashflows_from_investing_activities,
|
|
16
|
+
:net_borrowings,
|
|
17
|
+
:total_cash_from_financing_activities,
|
|
18
|
+
:change_to_operating_activities,
|
|
19
|
+
:net_income,
|
|
20
|
+
:change_in_cash,
|
|
21
|
+
:begin_period_cash_flow,
|
|
22
|
+
:end_period_cash_flow,
|
|
23
|
+
:total_cash_from_operating_activities,
|
|
24
|
+
:issuance_of_capital_stock,
|
|
25
|
+
:depreciation,
|
|
26
|
+
:other_cashflows_from_investing_activities,
|
|
27
|
+
:dividends_paid,
|
|
28
|
+
:change_to_inventory,
|
|
29
|
+
:change_to_account_receivables,
|
|
30
|
+
:sale_purchase_of_stock,
|
|
31
|
+
:other_cashflows_from_financing_activities,
|
|
32
|
+
:change_to_netincome,
|
|
33
|
+
:capital_expenditures,
|
|
34
|
+
:change_receivables,
|
|
35
|
+
:cash_flows_other_operating,
|
|
36
|
+
:exchange_rate_changes,
|
|
37
|
+
:cash_and_cash_equivalents_changes,
|
|
38
|
+
:change_in_working_capital,
|
|
39
|
+
:stock_based_compensation,
|
|
40
|
+
:other_non_cash_items,
|
|
41
|
+
:free_cash_flow
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def initialize(data)
|
|
46
|
+
@date = data['date']
|
|
47
|
+
@filing_date = data['filing_date']
|
|
48
|
+
@currency_symbol = data['currency_symbol']
|
|
49
|
+
@investments = data['investments']
|
|
50
|
+
@change_to_liabilities = data['changeToLiabilities']
|
|
51
|
+
@total_cashflows_from_investing_activities = data['totalCashflowsFromInvestingActivities']
|
|
52
|
+
@net_borrowings = data['netBorrowings']
|
|
53
|
+
@total_cash_from_financing_activities = data['totalCashFromFinancingActivities']
|
|
54
|
+
@change_to_operating_activities = data['changeToOperatingActivities']
|
|
55
|
+
@net_income = data['netIncome']
|
|
56
|
+
@change_in_cash = data['changeInCash']
|
|
57
|
+
@begin_period_cash_flow = data['beginPeriodCashFlow']
|
|
58
|
+
@end_period_cash_flow = data['endPeriodCashFlow']
|
|
59
|
+
@total_cash_from_operating_activities = data['totalCashFromOperatingActivities']
|
|
60
|
+
@issuance_of_capital_stock = data['issuanceOfCapitalStock']
|
|
61
|
+
@depreciation = data['depreciation']
|
|
62
|
+
@other_cashflows_from_investing_activities = data['otherCashflowsFromInvestingActivities']
|
|
63
|
+
@dividends_paid = data['dividendsPaid']
|
|
64
|
+
@change_to_inventory = data['changeToInventory']
|
|
65
|
+
@change_to_account_receivables = data['changeToAccountReceivables']
|
|
66
|
+
@sale_purchase_of_stock = data['salePurchaseOfStock']
|
|
67
|
+
@other_cashflows_from_financing_activities = data['otherCashflowsFromFinancingActivities']
|
|
68
|
+
@change_to_netincome = data['changeToNetincome']
|
|
69
|
+
@capital_expenditures = data['capitalExpenditures']
|
|
70
|
+
@change_receivables = data['changeReceivables']
|
|
71
|
+
@cash_flows_other_operating = data['cashFlowsOtherOperating']
|
|
72
|
+
@exchange_rate_changes = data['exchangeRateChanges']
|
|
73
|
+
@cash_and_cash_equivalents_changes = data['cashAndCashEquivalentsChanges']
|
|
74
|
+
@change_in_working_capital = data['changeInWorkingCapital']
|
|
75
|
+
@stock_based_compensation = data['stockBasedCompensation']
|
|
76
|
+
@other_non_cash_items = data['otherNonCashItems']
|
|
77
|
+
@free_cash_flow = data['freeCashFlow']
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Financials/CashFlow.rb
|
|
2
|
+
# Eodhd::Fundamentals::Financials::CashFlow
|
|
3
|
+
|
|
4
|
+
require_relative './CashFlow/Entry'
|
|
5
|
+
|
|
6
|
+
class Eodhd
|
|
7
|
+
class Fundamentals
|
|
8
|
+
class Financials
|
|
9
|
+
class CashFlow
|
|
10
|
+
attr_reader\
|
|
11
|
+
:quarterly,
|
|
12
|
+
:yearly
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def initialize(data)
|
|
17
|
+
@yearly = wrap(data['yearly'])
|
|
18
|
+
@quarterly = wrap(data['quarterly'])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def wrap(entries)
|
|
22
|
+
return [] unless entries
|
|
23
|
+
entries.values.map{|entry| Entry.new(entry)}.sort_by(&:date)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Financials/IncomeStatement/Entry.rb
|
|
2
|
+
# Eodhd::Fundamentals::Financials::IncomeStatement::Entry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Financials
|
|
7
|
+
class IncomeStatement
|
|
8
|
+
class Entry
|
|
9
|
+
attr_reader\
|
|
10
|
+
:date,
|
|
11
|
+
:filing_date,
|
|
12
|
+
:currency_symbol,
|
|
13
|
+
:research_development,
|
|
14
|
+
:effect_of_accounting_charges,
|
|
15
|
+
:income_before_tax,
|
|
16
|
+
:minority_interest,
|
|
17
|
+
:net_income,
|
|
18
|
+
:selling_general_administrative,
|
|
19
|
+
:selling_and_marketing_expenses,
|
|
20
|
+
:gross_profit,
|
|
21
|
+
:reconciled_depreciation,
|
|
22
|
+
:ebit,
|
|
23
|
+
:ebitda,
|
|
24
|
+
:depreciation_and_amortization,
|
|
25
|
+
:non_operating_income_net_other,
|
|
26
|
+
:operating_income,
|
|
27
|
+
:other_operating_expenses,
|
|
28
|
+
:interest_expense,
|
|
29
|
+
:tax_provision,
|
|
30
|
+
:interest_income,
|
|
31
|
+
:net_interest_income,
|
|
32
|
+
:extraordinary_items,
|
|
33
|
+
:non_recurring,
|
|
34
|
+
:other_items,
|
|
35
|
+
:income_tax_expense,
|
|
36
|
+
:total_revenue,
|
|
37
|
+
:total_operating_expenses,
|
|
38
|
+
:cost_of_revenue,
|
|
39
|
+
:total_other_income_expense_net,
|
|
40
|
+
:discontinued_operations,
|
|
41
|
+
:net_income_from_continuing_operations,
|
|
42
|
+
:net_income_applicable_to_common_shares,
|
|
43
|
+
:preferred_stock_and_other_adjustments
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def initialize(data)
|
|
48
|
+
@date = data['date']
|
|
49
|
+
@filing_date = data['filing_date']
|
|
50
|
+
@currency_symbol = data['currency_symbol']
|
|
51
|
+
@research_development = data['researchDevelopment']
|
|
52
|
+
@effect_of_accounting_charges = data['effectOfAccountingCharges']
|
|
53
|
+
@income_before_tax = data['incomeBeforeTax']
|
|
54
|
+
@minority_interest = data['minorityInterest']
|
|
55
|
+
@net_income = data['netIncome']
|
|
56
|
+
@selling_general_administrative = data['sellingGeneralAdministrative']
|
|
57
|
+
@selling_and_marketing_expenses = data['sellingAndMarketingExpenses']
|
|
58
|
+
@gross_profit = data['grossProfit']
|
|
59
|
+
@reconciled_depreciation = data['reconciledDepreciation']
|
|
60
|
+
@ebit = data['ebit']
|
|
61
|
+
@ebitda = data['ebitda']
|
|
62
|
+
@depreciation_and_amortization = data['depreciationAndAmortization']
|
|
63
|
+
@non_operating_income_net_other = data['nonOperatingIncomeNetOther']
|
|
64
|
+
@operating_income = data['operatingIncome']
|
|
65
|
+
@other_operating_expenses = data['otherOperatingExpenses']
|
|
66
|
+
@interest_expense = data['interestExpense']
|
|
67
|
+
@tax_provision = data['taxProvision']
|
|
68
|
+
@interest_income = data['interestIncome']
|
|
69
|
+
@net_interest_income = data['netInterestIncome']
|
|
70
|
+
@extraordinary_items = data['extraordinaryItems']
|
|
71
|
+
@non_recurring = data['nonRecurring']
|
|
72
|
+
@other_items = data['otherItems']
|
|
73
|
+
@income_tax_expense = data['incomeTaxExpense']
|
|
74
|
+
@total_revenue = data['totalRevenue']
|
|
75
|
+
@total_operating_expenses = data['totalOperatingExpenses']
|
|
76
|
+
@cost_of_revenue = data['costOfRevenue']
|
|
77
|
+
@total_other_income_expense_net = data['totalOtherIncomeExpenseNet']
|
|
78
|
+
@discontinued_operations = data['discontinuedOperations']
|
|
79
|
+
@net_income_from_continuing_operations = data['netIncomeFromContinuingOps']
|
|
80
|
+
@net_income_applicable_to_common_shares = data['netIncomeApplicableToCommonShares']
|
|
81
|
+
@preferred_stock_and_other_adjustments = data['preferredStockAndOtherAdjustments']
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Financials/IncomeStatement.rb
|
|
2
|
+
# Eodhd::Fundamentals::Financials::IncomeStatement
|
|
3
|
+
|
|
4
|
+
require_relative './IncomeStatement/Entry'
|
|
5
|
+
|
|
6
|
+
class Eodhd
|
|
7
|
+
class Fundamentals
|
|
8
|
+
class Financials
|
|
9
|
+
class IncomeStatement
|
|
10
|
+
attr_reader\
|
|
11
|
+
:quarterly,
|
|
12
|
+
:yearly
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def initialize(data)
|
|
17
|
+
@yearly = wrap(data['yearly'])
|
|
18
|
+
@quarterly = wrap(data['quarterly'])
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def wrap(entries)
|
|
22
|
+
return [] unless entries
|
|
23
|
+
entries.values.map{|entry| Entry.new(entry)}.sort_by(&:date)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Eodhd/Fundamentals/Financials.rb
|
|
2
2
|
# Eodhd::Fundamentals::Financials
|
|
3
3
|
|
|
4
|
-
require_relative './Financials/
|
|
4
|
+
require_relative './Financials/BalanceSheet'
|
|
5
|
+
require_relative './Financials/CashFlow'
|
|
6
|
+
require_relative './Financials/IncomeStatement'
|
|
5
7
|
|
|
6
8
|
class Eodhd
|
|
7
9
|
class Fundamentals
|
|
@@ -14,9 +16,9 @@ class Eodhd
|
|
|
14
16
|
private
|
|
15
17
|
|
|
16
18
|
def initialize(data)
|
|
17
|
-
@income_statement =
|
|
18
|
-
@balance_sheet =
|
|
19
|
-
@cash_flow =
|
|
19
|
+
@income_statement = IncomeStatement.new(data['Income_Statement']) if data['Income_Statement']
|
|
20
|
+
@balance_sheet = BalanceSheet.new(data['Balance_Sheet']) if data['Balance_Sheet']
|
|
21
|
+
@cash_flow = CashFlow.new(data['Cash_Flow']) if data['Cash_Flow']
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Holders/Fund.rb
|
|
2
|
+
# Eodhd::Fundamentals::Holders::Fund
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Holders
|
|
7
|
+
class Fund
|
|
8
|
+
attr_reader\
|
|
9
|
+
:name,
|
|
10
|
+
:date,
|
|
11
|
+
:total_shares,
|
|
12
|
+
:total_assets,
|
|
13
|
+
:current_shares,
|
|
14
|
+
:change,
|
|
15
|
+
:change_percent
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def initialize(data)
|
|
20
|
+
@name = data['name']
|
|
21
|
+
@date = data['date']
|
|
22
|
+
@total_shares = data['totalShares']
|
|
23
|
+
@total_assets = data['totalAssets']
|
|
24
|
+
@current_shares = data['currentShares']
|
|
25
|
+
@change = data['change']
|
|
26
|
+
@change_percent = data['change_p']
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/Holders/Institution.rb
|
|
2
|
+
# Eodhd::Fundamentals::Holders::Institution
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class Holders
|
|
7
|
+
class Institution
|
|
8
|
+
attr_reader\
|
|
9
|
+
:name,
|
|
10
|
+
:date,
|
|
11
|
+
:total_shares,
|
|
12
|
+
:total_assets,
|
|
13
|
+
:current_shares,
|
|
14
|
+
:change,
|
|
15
|
+
:change_percent
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def initialize(data)
|
|
20
|
+
@name = data['name']
|
|
21
|
+
@date = data['date']
|
|
22
|
+
@total_shares = data['totalShares']
|
|
23
|
+
@total_assets = data['totalAssets']
|
|
24
|
+
@current_shares = data['currentShares']
|
|
25
|
+
@change = data['change']
|
|
26
|
+
@change_percent = data['change_p']
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# Eodhd/Fundamentals/Holders.rb
|
|
2
2
|
# Eodhd::Fundamentals::Holders
|
|
3
3
|
|
|
4
|
+
require_relative './Holders/Institution'
|
|
5
|
+
require_relative './Holders/Fund'
|
|
6
|
+
|
|
4
7
|
class Eodhd
|
|
5
8
|
class Fundamentals
|
|
6
9
|
class Holders
|
|
@@ -11,8 +14,13 @@ class Eodhd
|
|
|
11
14
|
private
|
|
12
15
|
|
|
13
16
|
def initialize(data)
|
|
14
|
-
@institutions = data['Institutions']
|
|
15
|
-
@funds = data['Funds']
|
|
17
|
+
@institutions = wrap(data['Institutions'], Institution)
|
|
18
|
+
@funds = wrap(data['Funds'], Fund)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def wrap(entries, entry_class)
|
|
22
|
+
return [] unless entries
|
|
23
|
+
entries.values.map{|entry| entry_class.new(entry)}
|
|
16
24
|
end
|
|
17
25
|
end
|
|
18
26
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/InsiderTransaction.rb
|
|
2
|
+
# Eodhd::Fundamentals::InsiderTransaction
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class InsiderTransaction
|
|
7
|
+
attr_reader\
|
|
8
|
+
:date,
|
|
9
|
+
:owner_cik,
|
|
10
|
+
:owner_name,
|
|
11
|
+
:transaction_date,
|
|
12
|
+
:transaction_code,
|
|
13
|
+
:transaction_amount,
|
|
14
|
+
:transaction_price,
|
|
15
|
+
:transaction_acquired_disposed,
|
|
16
|
+
:post_transaction_amount,
|
|
17
|
+
:sec_link
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def initialize(data)
|
|
22
|
+
@date = data['date']
|
|
23
|
+
@owner_cik = data['ownerCik']
|
|
24
|
+
@owner_name = data['ownerName']
|
|
25
|
+
@transaction_date = data['transactionDate']
|
|
26
|
+
@transaction_code = data['transactionCode']
|
|
27
|
+
@transaction_amount = data['transactionAmount']
|
|
28
|
+
@transaction_price = data['transactionPrice']
|
|
29
|
+
@transaction_acquired_disposed = data['transactionAcquiredDisposed']
|
|
30
|
+
@post_transaction_amount = data['postTransactionAmount']
|
|
31
|
+
@sec_link = data['secLink']
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/OutstandingShares/Entry.rb
|
|
2
|
+
# Eodhd::Fundamentals::OutstandingShares::Entry
|
|
3
|
+
|
|
4
|
+
class Eodhd
|
|
5
|
+
class Fundamentals
|
|
6
|
+
class OutstandingShares
|
|
7
|
+
class Entry
|
|
8
|
+
attr_reader\
|
|
9
|
+
:date,
|
|
10
|
+
:date_formatted,
|
|
11
|
+
:shares_mln,
|
|
12
|
+
:shares
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def initialize(data)
|
|
17
|
+
@date = data['date']
|
|
18
|
+
@date_formatted = data['dateFormatted']
|
|
19
|
+
@shares_mln = data['sharesMln']
|
|
20
|
+
@shares = data['shares']
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Eodhd/Fundamentals/OutstandingShares.rb
|
|
2
|
+
# Eodhd::Fundamentals::OutstandingShares
|
|
3
|
+
|
|
4
|
+
require_relative './OutstandingShares/Entry'
|
|
5
|
+
|
|
6
|
+
class Eodhd
|
|
7
|
+
class Fundamentals
|
|
8
|
+
class OutstandingShares
|
|
9
|
+
attr_reader\
|
|
10
|
+
:annual,
|
|
11
|
+
:quarterly
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def initialize(data)
|
|
16
|
+
@annual = wrap(data['annual'])
|
|
17
|
+
@quarterly = wrap(data['quarterly'])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def wrap(entries)
|
|
21
|
+
return [] unless entries
|
|
22
|
+
entries.values.map{|entry| Entry.new(entry)}.sort_by(&:date)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
data/lib/Eodhd/Fundamentals.rb
CHANGED
|
@@ -8,6 +8,8 @@ require_relative './Fundamentals/Financials'
|
|
|
8
8
|
require_relative './Fundamentals/General'
|
|
9
9
|
require_relative './Fundamentals/Highlights'
|
|
10
10
|
require_relative './Fundamentals/Holders'
|
|
11
|
+
require_relative './Fundamentals/InsiderTransaction'
|
|
12
|
+
require_relative './Fundamentals/OutstandingShares'
|
|
11
13
|
require_relative './Fundamentals/SharesStats'
|
|
12
14
|
require_relative './Fundamentals/SplitsDividends'
|
|
13
15
|
require_relative './Fundamentals/Technicals'
|
|
@@ -75,11 +77,16 @@ class Eodhd
|
|
|
75
77
|
@splits_dividends = SplitsDividends.new(splits_dividends) if splits_dividends
|
|
76
78
|
@analyst_ratings = AnalystRatings.new(analyst_ratings) if analyst_ratings
|
|
77
79
|
@holders = Holders.new(holders) if holders
|
|
78
|
-
@insider_transactions = insider_transactions
|
|
80
|
+
@insider_transactions = wrap_insider_transactions(insider_transactions)
|
|
79
81
|
@esg_scores = ESGScores.new(esg_scores) if esg_scores
|
|
80
|
-
@outstanding_shares = outstanding_shares
|
|
82
|
+
@outstanding_shares = OutstandingShares.new(outstanding_shares) if outstanding_shares
|
|
81
83
|
@earnings = Earnings.new(earnings) if earnings
|
|
82
84
|
@financials = Financials.new(financials) if financials
|
|
83
85
|
end
|
|
86
|
+
|
|
87
|
+
def wrap_insider_transactions(entries)
|
|
88
|
+
return [] unless entries
|
|
89
|
+
entries.values.map{|entry| InsiderTransaction.new(entry)}.sort_by(&:date)
|
|
90
|
+
end
|
|
84
91
|
end
|
|
85
92
|
end
|
data/lib/Eodhd/VERSION.rb
CHANGED
|
@@ -47,18 +47,40 @@ describe Eodhd::Fundamentals do
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
it "returns Financials with income_statement, balance_sheet, and cash_flow" do
|
|
50
|
+
it "returns Financials with typed income_statement, balance_sheet, and cash_flow" do
|
|
51
51
|
VCR.use_cassette('fundamentals_aapl') do
|
|
52
|
-
_(fd.financials.income_statement).must_be_kind_of(Eodhd::Fundamentals::Financials::
|
|
53
|
-
_(fd.financials.balance_sheet).must_be_kind_of(Eodhd::Fundamentals::Financials::
|
|
54
|
-
_(fd.financials.cash_flow).must_be_kind_of(Eodhd::Fundamentals::Financials::
|
|
52
|
+
_(fd.financials.income_statement).must_be_kind_of(Eodhd::Fundamentals::Financials::IncomeStatement)
|
|
53
|
+
_(fd.financials.balance_sheet).must_be_kind_of(Eodhd::Fundamentals::Financials::BalanceSheet)
|
|
54
|
+
_(fd.financials.cash_flow).must_be_kind_of(Eodhd::Fundamentals::Financials::CashFlow)
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
it "returns quarterly and yearly
|
|
58
|
+
it "returns quarterly and yearly as sorted arrays of typed entries" do
|
|
59
59
|
VCR.use_cassette('fundamentals_aapl') do
|
|
60
|
-
|
|
61
|
-
_(
|
|
60
|
+
yearly = fd.financials.balance_sheet.yearly
|
|
61
|
+
_(yearly).must_be_kind_of(Array)
|
|
62
|
+
_(yearly.first).must_be_kind_of(Eodhd::Fundamentals::Financials::BalanceSheet::Entry)
|
|
63
|
+
_(fd.financials.balance_sheet.quarterly).must_be_kind_of(Array)
|
|
64
|
+
dates = yearly.map(&:date)
|
|
65
|
+
_(dates).must_equal(dates.sort)
|
|
66
|
+
_(dates.first).must_equal('1985-09-30')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "resolves interpreted and typo-corrected balance sheet accessors" do
|
|
71
|
+
VCR.use_cassette('fundamentals_aapl') do
|
|
72
|
+
latest = fd.financials.balance_sheet.yearly.last
|
|
73
|
+
_(latest.date).must_equal('2025-09-30')
|
|
74
|
+
_(latest.total_liabilities).must_equal('285508000000.00') # totalLiab
|
|
75
|
+
_(latest.capital_surplus).must_equal('93567852270.00') # capitalSurpluse (misspelling corrected)
|
|
76
|
+
_(latest.non_current_assets_other).must_equal('62950000000.00') # nonCurrrentAssetsOther (typo corrected)
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "expands abbreviated income statement accessors" do
|
|
81
|
+
VCR.use_cassette('fundamentals_aapl') do
|
|
82
|
+
latest = fd.financials.income_statement.yearly.last
|
|
83
|
+
_(latest.net_income_from_continuing_operations).must_equal('112010000000.00') # netIncomeFromContinuingOps
|
|
62
84
|
end
|
|
63
85
|
end
|
|
64
86
|
|
|
@@ -68,6 +90,44 @@ describe Eodhd::Fundamentals do
|
|
|
68
90
|
end
|
|
69
91
|
end
|
|
70
92
|
|
|
93
|
+
it "returns Earnings annual, history, and trend as arrays of typed entries" do
|
|
94
|
+
VCR.use_cassette('fundamentals_aapl') do
|
|
95
|
+
_(fd.earnings.annual.first).must_be_kind_of(Eodhd::Fundamentals::Earnings::AnnualEntry)
|
|
96
|
+
_(fd.earnings.history.first).must_be_kind_of(Eodhd::Fundamentals::Earnings::HistoryEntry)
|
|
97
|
+
_(fd.earnings.trend.first).must_be_kind_of(Eodhd::Fundamentals::Earnings::TrendEntry)
|
|
98
|
+
dates = fd.earnings.annual.map(&:date)
|
|
99
|
+
_(dates).must_equal(dates.sort)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "returns Holders institutions and funds as arrays of typed entries" do
|
|
104
|
+
VCR.use_cassette('fundamentals_aapl') do
|
|
105
|
+
_(fd.holders.institutions).must_be_kind_of(Array)
|
|
106
|
+
_(fd.holders.funds).must_be_kind_of(Array)
|
|
107
|
+
institution = fd.holders.institutions.first
|
|
108
|
+
_(institution).must_be_kind_of(Eodhd::Fundamentals::Holders::Institution)
|
|
109
|
+
_(institution.name).must_equal('Vanguard Group Inc')
|
|
110
|
+
_(institution.change_percent).must_equal(1.9191) # change_p
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
it "returns insider_transactions as a sorted array of InsiderTransaction" do
|
|
115
|
+
VCR.use_cassette('fundamentals_aapl') do
|
|
116
|
+
_(fd.insider_transactions).must_be_kind_of(Array)
|
|
117
|
+
_(fd.insider_transactions.first).must_be_kind_of(Eodhd::Fundamentals::InsiderTransaction)
|
|
118
|
+
dates = fd.insider_transactions.map(&:date)
|
|
119
|
+
_(dates).must_equal(dates.sort)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "returns outstanding_shares as OutstandingShares with typed annual and quarterly arrays" do
|
|
124
|
+
VCR.use_cassette('fundamentals_aapl') do
|
|
125
|
+
_(fd.outstanding_shares).must_be_kind_of(Eodhd::Fundamentals::OutstandingShares)
|
|
126
|
+
_(fd.outstanding_shares.annual.first).must_be_kind_of(Eodhd::Fundamentals::OutstandingShares::Entry)
|
|
127
|
+
_(fd.outstanding_shares.quarterly.first).must_be_kind_of(Eodhd::Fundamentals::OutstandingShares::Entry)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
71
131
|
it "returns SharesStats as an Eodhd::Fundamentals::SharesStats" do
|
|
72
132
|
VCR.use_cassette('fundamentals_aapl') do
|
|
73
133
|
_(fd.shares_stats).must_be_kind_of(Eodhd::Fundamentals::SharesStats)
|
|
@@ -75,4 +135,29 @@ describe Eodhd::Fundamentals do
|
|
|
75
135
|
end
|
|
76
136
|
end
|
|
77
137
|
end
|
|
138
|
+
|
|
139
|
+
describe ".all with an ASX symbol" do
|
|
140
|
+
let(:fd){Eodhd::Fundamentals.all(api_token: api_token, exchange_code: 'AU', symbol: 'CBA')}
|
|
141
|
+
|
|
142
|
+
it "wraps a real AU fundamentals payload into the same typed objects" do
|
|
143
|
+
VCR.use_cassette('fundamentals_cba_au') do
|
|
144
|
+
_(fd).must_be_kind_of(Eodhd::Fundamentals)
|
|
145
|
+
_(fd.exchange_code).must_equal('AU')
|
|
146
|
+
_(fd.symbol).must_equal('CBA')
|
|
147
|
+
_(fd.general).must_be_kind_of(Eodhd::Fundamentals::General)
|
|
148
|
+
|
|
149
|
+
_(fd.financials.balance_sheet).must_be_kind_of(Eodhd::Fundamentals::Financials::BalanceSheet)
|
|
150
|
+
yearly = fd.financials.balance_sheet.yearly
|
|
151
|
+
_(yearly).must_be_kind_of(Array)
|
|
152
|
+
_(yearly).wont_be_empty
|
|
153
|
+
_(yearly.first).must_be_kind_of(Eodhd::Fundamentals::Financials::BalanceSheet::Entry)
|
|
154
|
+
dates = yearly.map(&:date)
|
|
155
|
+
_(dates).must_equal(dates.sort)
|
|
156
|
+
|
|
157
|
+
_(fd.holders.institutions).must_be_kind_of(Array)
|
|
158
|
+
_(fd.insider_transactions).must_be_kind_of(Array)
|
|
159
|
+
_(fd.outstanding_shares).must_be_kind_of(Eodhd::Fundamentals::OutstandingShares)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
78
163
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eodhd.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.19.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- thoran
|
|
@@ -157,11 +157,24 @@ files:
|
|
|
157
157
|
- lib/Eodhd/Fundamentals/AnalystRatings.rb
|
|
158
158
|
- lib/Eodhd/Fundamentals/ESGScores.rb
|
|
159
159
|
- lib/Eodhd/Fundamentals/Earnings.rb
|
|
160
|
+
- lib/Eodhd/Fundamentals/Earnings/AnnualEntry.rb
|
|
161
|
+
- lib/Eodhd/Fundamentals/Earnings/HistoryEntry.rb
|
|
162
|
+
- lib/Eodhd/Fundamentals/Earnings/TrendEntry.rb
|
|
160
163
|
- lib/Eodhd/Fundamentals/Financials.rb
|
|
161
|
-
- lib/Eodhd/Fundamentals/Financials/
|
|
164
|
+
- lib/Eodhd/Fundamentals/Financials/BalanceSheet.rb
|
|
165
|
+
- lib/Eodhd/Fundamentals/Financials/BalanceSheet/Entry.rb
|
|
166
|
+
- lib/Eodhd/Fundamentals/Financials/CashFlow.rb
|
|
167
|
+
- lib/Eodhd/Fundamentals/Financials/CashFlow/Entry.rb
|
|
168
|
+
- lib/Eodhd/Fundamentals/Financials/IncomeStatement.rb
|
|
169
|
+
- lib/Eodhd/Fundamentals/Financials/IncomeStatement/Entry.rb
|
|
162
170
|
- lib/Eodhd/Fundamentals/General.rb
|
|
163
171
|
- lib/Eodhd/Fundamentals/Highlights.rb
|
|
164
172
|
- lib/Eodhd/Fundamentals/Holders.rb
|
|
173
|
+
- lib/Eodhd/Fundamentals/Holders/Fund.rb
|
|
174
|
+
- lib/Eodhd/Fundamentals/Holders/Institution.rb
|
|
175
|
+
- lib/Eodhd/Fundamentals/InsiderTransaction.rb
|
|
176
|
+
- lib/Eodhd/Fundamentals/OutstandingShares.rb
|
|
177
|
+
- lib/Eodhd/Fundamentals/OutstandingShares/Entry.rb
|
|
165
178
|
- lib/Eodhd/Fundamentals/SharesStats.rb
|
|
166
179
|
- lib/Eodhd/Fundamentals/SplitsDividends.rb
|
|
167
180
|
- lib/Eodhd/Fundamentals/Technicals.rb
|
|
@@ -198,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
198
211
|
- !ruby/object:Gem::Version
|
|
199
212
|
version: '0'
|
|
200
213
|
requirements: []
|
|
201
|
-
rubygems_version: 4.0.
|
|
214
|
+
rubygems_version: 4.0.18
|
|
202
215
|
specification_version: 4
|
|
203
216
|
summary: Access the eodhd.com API with Ruby.
|
|
204
217
|
test_files: []
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# Eodhd/Fundamentals/Financials/Statement.rb
|
|
2
|
-
# Eodhd::Fundamentals::Financials::Statement
|
|
3
|
-
|
|
4
|
-
class Eodhd
|
|
5
|
-
class Fundamentals
|
|
6
|
-
class Financials
|
|
7
|
-
class Statement
|
|
8
|
-
attr_reader\
|
|
9
|
-
:quarterly,
|
|
10
|
-
:yearly
|
|
11
|
-
|
|
12
|
-
private
|
|
13
|
-
|
|
14
|
-
def initialize(data)
|
|
15
|
-
@quarterly = data['quarterly']
|
|
16
|
-
@yearly = data['yearly']
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|