ya_finance 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +7 -0
- data/bin/yafin +13 -0
- data/lib/ya_finance/current.rb +33 -0
- data/lib/ya_finance/format.rb +7 -0
- data/lib/ya_finance/future.rb +25 -0
- data/lib/ya_finance/http.rb +84 -0
- data/lib/ya_finance/meta.rb +34 -0
- data/lib/ya_finance/past.rb +43 -0
- data/lib/ya_finance/results.rb +46 -0
- data/lib/ya_finance/scrapper/calendar.rb +20 -0
- data/lib/ya_finance/scrapper/holders.rb +16 -0
- data/lib/ya_finance.rb +30 -0
- metadata +54 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 49c7b3c1fb624d9d1a2e6ebe0225a51ed539cb4985311e80450da25dc8bb3a13
|
|
4
|
+
data.tar.gz: 502d58da08e1093560906b4fbd881f7709413c3d70a20dba36ed7837dfd5203a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 8a63b22a1428d87b29790fd3a8cdaea223c941547f042d5583f23f9b589a08c7825c5969a710c1121335fc6fc7d79c92aba8622b789efa4660fa9f15b4ca1f9a
|
|
7
|
+
data.tar.gz: 330186bd6f07c1ce612d137c907471d5a2795391a30e28ff36505ff0e9eeb75c30596df61357934548f4bfee1c0e492c0cb145859952081957e4b916dc895f4e
|
data/Gemfile
ADDED
data/bin/yafin
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require_relative '../lib/ya_finance'
|
|
3
|
+
|
|
4
|
+
def to_upcase(str)
|
|
5
|
+
str.split('_').map(&:capitalize).join('')
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
if ARGV[0] && ARGV[1] && ARGV[2]
|
|
9
|
+
puts YaFinance.new(ARGV[0]).send(ARGV[1].to_sym).send(ARGV[2].to_sym).to_json
|
|
10
|
+
else
|
|
11
|
+
puts "Usage:"
|
|
12
|
+
puts "$ yafin TICKER context action"
|
|
13
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require_relative 'http'
|
|
3
|
+
|
|
4
|
+
class YaFinance
|
|
5
|
+
class Current
|
|
6
|
+
include Http::FetchV6
|
|
7
|
+
include Http::FetchV7
|
|
8
|
+
include Http::FetchHistorical
|
|
9
|
+
|
|
10
|
+
def initialize(ticker, options={})
|
|
11
|
+
@ticker = ticker
|
|
12
|
+
@options = options
|
|
13
|
+
end
|
|
14
|
+
def price
|
|
15
|
+
pris = fetch_v6('price')['price']
|
|
16
|
+
[pris['currency'], pris['regularMarketPrice']['raw']]
|
|
17
|
+
end
|
|
18
|
+
def market_cap
|
|
19
|
+
pris = fetch_v6('price')['price']
|
|
20
|
+
[pris['currency'], pris['marketCap']['raw']]
|
|
21
|
+
end
|
|
22
|
+
def holders
|
|
23
|
+
response = fetch_historical("#{@ticker}/holders")
|
|
24
|
+
YaFinance::Scrapper::Holders.process(response)
|
|
25
|
+
end
|
|
26
|
+
def options
|
|
27
|
+
fetch_v7("options/#{@ticker}")['optionChain']['result'][0]['options']
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class YaFinance
|
|
2
|
+
class Future
|
|
3
|
+
def initialize(ticker, options)
|
|
4
|
+
end
|
|
5
|
+
def news
|
|
6
|
+
'PENDING' #V1
|
|
7
|
+
end
|
|
8
|
+
def revenue_forecasts
|
|
9
|
+
'PENDING'
|
|
10
|
+
end
|
|
11
|
+
def analyst_price_target
|
|
12
|
+
'PENDING'
|
|
13
|
+
end
|
|
14
|
+
def recommendations_summary
|
|
15
|
+
'PENDING'
|
|
16
|
+
end
|
|
17
|
+
def recommendations
|
|
18
|
+
'PENDING'
|
|
19
|
+
end
|
|
20
|
+
def calendar
|
|
21
|
+
'PENDING'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
class YaFinance::Http
|
|
2
|
+
ROOT_URL = 'https://finance.yahoo.com/'
|
|
3
|
+
QUERY_URL = "https://query2.finance.yahoo.com"
|
|
4
|
+
HISTORICAL_URL = "#{ROOT_URL}quote"
|
|
5
|
+
V8_URL = "#{QUERY_URL}/v8/finance"
|
|
6
|
+
V7_URL = "#{QUERY_URL}/v7/finance"
|
|
7
|
+
V6_URL = "#{QUERY_URL}/v6/finance/quoteSummary"
|
|
8
|
+
CHART_URL = 'https://ichart.finance.yahoo.com/x'
|
|
9
|
+
FUNDAMENTALS_URL = "#{QUERY_URL}/ws/fundamentals-timeseries/v1/finance/timeseries" # {0}?symbol={0}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def self.fetch(uri)
|
|
13
|
+
@@http ||= Net::HTTP::Persistent.new
|
|
14
|
+
@@http.override_headers["User-Agent"] = "YaFin/#{YaFinance::VERSION}"
|
|
15
|
+
@@http.request(uri)
|
|
16
|
+
end
|
|
17
|
+
def self.shutdown
|
|
18
|
+
@@http.shutdown
|
|
19
|
+
@@http = nil
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
module FetchRoot
|
|
23
|
+
def fetch_root(path)
|
|
24
|
+
uri = URI("#{ROOT_URL}/#{path}")
|
|
25
|
+
puts uri
|
|
26
|
+
# @TODO: make a crawler?
|
|
27
|
+
YaFinance::Http.fetch(uri).body
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module FetchHistorical
|
|
32
|
+
def fetch_historical(path)
|
|
33
|
+
uri = URI("#{HISTORICAL_URL}/#{path}")
|
|
34
|
+
puts uri
|
|
35
|
+
# @TODO: make a crawler?
|
|
36
|
+
YaFinance::Http.fetch(uri).body
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
module FetchFundamentals
|
|
41
|
+
def fetch_fundamentals(path)
|
|
42
|
+
uri = URI("#{FUNDAMENTALS_URL}/#{path}")
|
|
43
|
+
puts uri
|
|
44
|
+
# @TODO: make a crawler?
|
|
45
|
+
YaFinance::Http.fetch(uri).body
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
module FetchV7
|
|
50
|
+
def fetch_v7(path)
|
|
51
|
+
uri = URI("#{V7_URL}/#{path}")
|
|
52
|
+
puts uri
|
|
53
|
+
JSON.parse(YaFinance::Http.fetch(uri).body)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
module FetchV8
|
|
57
|
+
def fetch_v8(path)
|
|
58
|
+
uri = URI("#{V8_URL}/#{path}")
|
|
59
|
+
puts uri
|
|
60
|
+
JSON.parse(YaFinance::Http.fetch(uri).body)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module FetchV6
|
|
65
|
+
def fetch_v6(mod)
|
|
66
|
+
# modules = ['financialData', 'quoteType', 'defaultKeyStatistics', 'assetProfile', 'summaryDetail']
|
|
67
|
+
uri = URI("#{V6_URL}/#{ERB::Util.url_encode(@ticker)}?modules=#{mod}")
|
|
68
|
+
puts "#{uri}"
|
|
69
|
+
json = JSON.parse(YaFinance::Http.fetch(uri).body)
|
|
70
|
+
YaFinance::Http.shutdown
|
|
71
|
+
|
|
72
|
+
if json["quoteSummary"] && json["quoteSummary"]["error"]
|
|
73
|
+
return json["quoteSummary"]["error"]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
result = json["quoteSummary"]&.dig("result", 0)
|
|
77
|
+
return nil if result.nil?
|
|
78
|
+
|
|
79
|
+
result
|
|
80
|
+
rescue Net::HTTPBadResponse, Net::HTTPNotFound, Net::HTTPError, Net::HTTPServerError, JSON::ParserError
|
|
81
|
+
return "HTTP Error"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require_relative 'http'
|
|
2
|
+
|
|
3
|
+
class YaFinance
|
|
4
|
+
class Meta
|
|
5
|
+
include Http::FetchV6
|
|
6
|
+
include Http::FetchRoot
|
|
7
|
+
|
|
8
|
+
def initialize(ticker, options)
|
|
9
|
+
@ticker = ticker
|
|
10
|
+
@options = options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def earnings_calendar
|
|
14
|
+
html = fetch_root("calendar/earnings?symbol=#{@ticker}&offset=0&size=1000")
|
|
15
|
+
YaFinance::Scrapper::Calendar.process(html)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def short_name
|
|
19
|
+
fetch_v6('price')['price']['shortName']
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def shares
|
|
23
|
+
# ...
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def info
|
|
27
|
+
# ...
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def sustainability
|
|
31
|
+
# ...
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
class YaFinance::Past
|
|
2
|
+
include YaFinance::Http::FetchV8
|
|
3
|
+
include YaFinance::Http::FetchRoot
|
|
4
|
+
|
|
5
|
+
ALL_EVENTS='div,splits,capitalGains'
|
|
6
|
+
OPTIONS='&includePrePost=False&interval=1d&range=5y'
|
|
7
|
+
|
|
8
|
+
def initialize(ticker, options)
|
|
9
|
+
@ticker = ticker
|
|
10
|
+
@options = options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# chart/GOOGL?events=&includePrePost=False&interval=1d&range=1y
|
|
14
|
+
|
|
15
|
+
def history
|
|
16
|
+
fetch_v8("chart/#{@ticker}?events=#{ALL_EVENTS}")['chart']['result'][0]
|
|
17
|
+
# @TODO: map timestamps
|
|
18
|
+
end
|
|
19
|
+
def dividends
|
|
20
|
+
evs = fetch_v8("chart/#{@ticker}?events=div#{OPTIONS}")['chart']['result'][0]['events']['dividends']
|
|
21
|
+
response = []
|
|
22
|
+
evs.map{|k,v| response.push({ "#{Date.parse(Time.at(v['date']).to_s)}" => v['amount'] })}
|
|
23
|
+
response
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def splits
|
|
27
|
+
evs = fetch_v8("chart/#{@ticker}?events=splits#{OPTIONS}")['chart']['result'][0]['events']['splits']
|
|
28
|
+
response = []
|
|
29
|
+
# {"1598880600"=>{"date"=>1598880600, "numerator"=>4.0, "denominator"=>1.0, "splitRatio"=>"4:1"}}
|
|
30
|
+
evs.map{|k,v| response.push({ "#{Date.parse(Time.at(v['date']).to_s)}" => v['amount'] })}
|
|
31
|
+
response
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def capital_gains
|
|
35
|
+
require 'byebug'
|
|
36
|
+
evs = fetch_v8("chart/#{@ticker}?events=capitalGains#{OPTIONS}")['chart']['result'][0]['events']
|
|
37
|
+
debugger
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def actions
|
|
41
|
+
# ...
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class YaFinance::Results
|
|
2
|
+
include YaFinance::Http::FetchFundamentals
|
|
3
|
+
|
|
4
|
+
# OPTIONS = "&type=annual"
|
|
5
|
+
FUNDAMENTALS = {
|
|
6
|
+
'financials': ["TaxEffectOfUnusualItems","TaxRateForCalcs","NormalizedEBITDA","NormalizedDilutedEPS","NormalizedBasicEPS","TotalUnusualItems","TotalUnusualItemsExcludingGoodwill","NetIncomeFromContinuingOperationNetMinorityInterest","ReconciledDepreciation","ReconciledCostOfRevenue","EBITDA","EBIT","NetInterestIncome","InterestExpense","InterestIncome","ContinuingAndDiscontinuedDilutedEPS","ContinuingAndDiscontinuedBasicEPS","NormalizedIncome","NetIncomeFromContinuingAndDiscontinuedOperation","TotalExpenses","RentExpenseSupplemental","ReportedNormalizedDilutedEPS","ReportedNormalizedBasicEPS","TotalOperatingIncomeAsReported","DividendPerShare","DilutedAverageShares","BasicAverageShares","DilutedEPS","DilutedEPSOtherGainsLosses","TaxLossCarryforwardDilutedEPS","DilutedAccountingChange","DilutedExtraordinary","DilutedDiscontinuousOperations","DilutedContinuousOperations","BasicEPS","BasicEPSOtherGainsLosses","TaxLossCarryforwardBasicEPS","BasicAccountingChange","BasicExtraordinary","BasicDiscontinuousOperations","BasicContinuousOperations","DilutedNIAvailtoComStockholders","AverageDilutionEarnings","NetIncomeCommonStockholders","OtherunderPreferredStockDividend","PreferredStockDividends","NetIncome","MinorityInterests","NetIncomeIncludingNoncontrollingInterests","NetIncomeFromTaxLossCarryforward","NetIncomeExtraordinary","NetIncomeDiscontinuousOperations","NetIncomeContinuousOperations","EarningsFromEquityInterestNetOfTax","TaxProvision","PretaxIncome","OtherIncomeExpense","OtherNonOperatingIncomeExpenses","SpecialIncomeCharges","GainOnSaleOfPPE","GainOnSaleOfBusiness","OtherSpecialCharges","WriteOff","ImpairmentOfCapitalAssets","RestructuringAndMergernAcquisition","SecuritiesAmortization","EarningsFromEquityInterest","GainOnSaleOfSecurity","NetNonOperatingInterestIncomeExpense","TotalOtherFinanceCost","InterestExpenseNonOperating","InterestIncomeNonOperating","OperatingIncome","OperatingExpense","OtherOperatingExpenses","OtherTaxes","ProvisionForDoubtfulAccounts","DepreciationAmortizationDepletionIncomeStatement","DepletionIncomeStatement","DepreciationAndAmortizationInIncomeStatement","Amortization","AmortizationOfIntangiblesIncomeStatement","DepreciationIncomeStatement","ResearchAndDevelopment","SellingGeneralAndAdministration","SellingAndMarketingExpense","GeneralAndAdministrativeExpense","OtherGandA","InsuranceAndClaims","RentAndLandingFees","SalariesAndWages","GrossProfit","CostOfRevenue","TotalRevenue","ExciseTaxes","OperatingRevenue"],
|
|
7
|
+
'balance-sheet': ["TreasurySharesNumber","PreferredSharesNumber","OrdinarySharesNumber","ShareIssued","NetDebt","TotalDebt","TangibleBookValue","InvestedCapital","WorkingCapital","NetTangibleAssets","CapitalLeaseObligations","CommonStockEquity","PreferredStockEquity","TotalCapitalization","TotalEquityGrossMinorityInterest","MinorityInterest","StockholdersEquity","OtherEquityInterest","GainsLossesNotAffectingRetainedEarnings","OtherEquityAdjustments","FixedAssetsRevaluationReserve","ForeignCurrencyTranslationAdjustments","MinimumPensionLiabilities","UnrealizedGainLoss","TreasuryStock","RetainedEarnings","AdditionalPaidInCapital","CapitalStock","OtherCapitalStock","CommonStock","PreferredStock","TotalPartnershipCapital","GeneralPartnershipCapital","LimitedPartnershipCapital","TotalLiabilitiesNetMinorityInterest","TotalNonCurrentLiabilitiesNetMinorityInterest","OtherNonCurrentLiabilities","LiabilitiesHeldforSaleNonCurrent","RestrictedCommonStock","PreferredSecuritiesOutsideStockEquity","DerivativeProductLiabilities","EmployeeBenefits","NonCurrentPensionAndOtherPostretirementBenefitPlans","NonCurrentAccruedExpenses","DuetoRelatedPartiesNonCurrent","TradeandOtherPayablesNonCurrent","NonCurrentDeferredLiabilities","NonCurrentDeferredRevenue","NonCurrentDeferredTaxesLiabilities","LongTermDebtAndCapitalLeaseObligation","LongTermCapitalLeaseObligation","LongTermDebt","LongTermProvisions","CurrentLiabilities","OtherCurrentLiabilities","CurrentDeferredLiabilities","CurrentDeferredRevenue","CurrentDeferredTaxesLiabilities","CurrentDebtAndCapitalLeaseObligation","CurrentCapitalLeaseObligation","CurrentDebt","OtherCurrentBorrowings","LineOfCredit","CommercialPaper","CurrentNotesPayable","PensionandOtherPostRetirementBenefitPlansCurrent","CurrentProvisions","PayablesAndAccruedExpenses","CurrentAccruedExpenses","InterestPayable","Payables","OtherPayable","DuetoRelatedPartiesCurrent","DividendsPayable","TotalTaxPayable","IncomeTaxPayable","AccountsPayable","TotalAssets","TotalNonCurrentAssets","OtherNonCurrentAssets","DefinedPensionBenefit","NonCurrentPrepaidAssets","NonCurrentDeferredAssets","NonCurrentDeferredTaxesAssets","DuefromRelatedPartiesNonCurrent","NonCurrentNoteReceivables","NonCurrentAccountsReceivable","FinancialAssets","InvestmentsAndAdvances","OtherInvestments","InvestmentinFinancialAssets","HeldToMaturitySecurities","AvailableForSaleSecurities","FinancialAssetsDesignatedasFairValueThroughProfitorLossTotal","TradingSecurities","LongTermEquityInvestment","InvestmentsinJointVenturesatCost","InvestmentsInOtherVenturesUnderEquityMethod","InvestmentsinAssociatesatCost","InvestmentsinSubsidiariesatCost","InvestmentProperties","GoodwillAndOtherIntangibleAssets","OtherIntangibleAssets","Goodwill","NetPPE","AccumulatedDepreciation","GrossPPE","Leases","ConstructionInProgress","OtherProperties","MachineryFurnitureEquipment","BuildingsAndImprovements","LandAndImprovements","Properties","CurrentAssets","OtherCurrentAssets","HedgingAssetsCurrent","AssetsHeldForSaleCurrent","CurrentDeferredAssets","CurrentDeferredTaxesAssets","RestrictedCash","PrepaidAssets","Inventory","InventoriesAdjustmentsAllowances","OtherInventories","FinishedGoods","WorkInProcess","RawMaterials","Receivables","ReceivablesAdjustmentsAllowances","OtherReceivables","DuefromRelatedPartiesCurrent","TaxesReceivable","AccruedInterestReceivable","NotesReceivable","LoansReceivable","AccountsReceivable","AllowanceForDoubtfulAccountsReceivable","GrossAccountsReceivable","CashCashEquivalentsAndShortTermInvestments","OtherShortTermInvestments","CashAndCashEquivalents","CashEquivalents","CashFinancial"],
|
|
8
|
+
'cash-flow': ["ForeignSales","DomesticSales","AdjustedGeographySegmentData","FreeCashFlow","RepurchaseOfCapitalStock","RepaymentOfDebt","IssuanceOfDebt","IssuanceOfCapitalStock","CapitalExpenditure","InterestPaidSupplementalData","IncomeTaxPaidSupplementalData","EndCashPosition","OtherCashAdjustmentOutsideChangeinCash","BeginningCashPosition","EffectOfExchangeRateChanges","ChangesInCash","OtherCashAdjustmentInsideChangeinCash","CashFlowFromDiscontinuedOperation","FinancingCashFlow","CashFromDiscontinuedFinancingActivities","CashFlowFromContinuingFinancingActivities","NetOtherFinancingCharges","InterestPaidCFF","ProceedsFromStockOptionExercised","CashDividendsPaid","PreferredStockDividendPaid","CommonStockDividendPaid","NetPreferredStockIssuance","PreferredStockPayments","PreferredStockIssuance","NetCommonStockIssuance","CommonStockPayments","CommonStockIssuance","NetIssuancePaymentsOfDebt","NetShortTermDebtIssuance","ShortTermDebtPayments","ShortTermDebtIssuance","NetLongTermDebtIssuance","LongTermDebtPayments","LongTermDebtIssuance","InvestingCashFlow","CashFromDiscontinuedInvestingActivities","CashFlowFromContinuingInvestingActivities","NetOtherInvestingChanges","InterestReceivedCFI","DividendsReceivedCFI","NetInvestmentPurchaseAndSale","SaleOfInvestment","PurchaseOfInvestment","NetInvestmentPropertiesPurchaseAndSale","SaleOfInvestmentProperties","PurchaseOfInvestmentProperties","NetBusinessPurchaseAndSale","SaleOfBusiness","PurchaseOfBusiness","NetIntangiblesPurchaseAndSale","SaleOfIntangibles","PurchaseOfIntangibles","NetPPEPurchaseAndSale","SaleOfPPE","PurchaseOfPPE","CapitalExpenditureReported","OperatingCashFlow","CashFromDiscontinuedOperatingActivities","CashFlowFromContinuingOperatingActivities","TaxesRefundPaid","InterestReceivedCFO","InterestPaidCFO","DividendReceivedCFO","DividendPaidCFO","ChangeInWorkingCapital","ChangeInOtherWorkingCapital","ChangeInOtherCurrentLiabilities","ChangeInOtherCurrentAssets","ChangeInPayablesAndAccruedExpense","ChangeInAccruedExpense","ChangeInInterestPayable","ChangeInPayable","ChangeInDividendPayable","ChangeInAccountPayable","ChangeInTaxPayable","ChangeInIncomeTaxPayable","ChangeInPrepaidAssets","ChangeInInventory","ChangeInReceivables","ChangesInAccountReceivables","OtherNonCashItems","ExcessTaxBenefitFromStockBasedCompensation","StockBasedCompensation","UnrealizedGainLossOnInvestmentSecurities","ProvisionandWriteOffofAssets","AssetImpairmentCharge","AmortizationOfSecurities","DeferredTax","DeferredIncomeTax","DepreciationAmortizationDepletion","Depletion","DepreciationAndAmortization","AmortizationCashFlow","AmortizationOfIntangibles","Depreciation","OperatingGainsLosses","PensionAndEmployeeBenefitExpense","EarningsLossesFromEquityInvestments","GainLossOnInvestmentSecurities","NetForeignCurrencyExchangeGainLoss","GainLossOnSaleOfPPE","GainLossOnSaleOfBusiness","NetIncomeFromContinuingOperations","CashFlowsfromusedinOperatingActivitiesDirect","TaxesRefundPaidDirect","InterestReceivedDirect","InterestPaidDirect","DividendsReceivedDirect","DividendsPaidDirect","ClassesofCashPayments","OtherCashPaymentsfromOperatingActivities","PaymentsonBehalfofEmployees","PaymentstoSuppliersforGoodsandServices","ClassesofCashReceiptsfromOperatingActivities","OtherCashReceiptsfromOperatingActivities","ReceiptsfromGovernmentGrants","ReceiptsfromCustomers"]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
def initialize(ticker, present, options)
|
|
12
|
+
@ticker = ticker
|
|
13
|
+
@present = present
|
|
14
|
+
@options = options
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def income_statement
|
|
18
|
+
fetch_fundamentals("#{@ticker}?symbol=#{@ticker}#{type('financials')}#{period}")
|
|
19
|
+
end
|
|
20
|
+
def balance_sheet
|
|
21
|
+
fetch_fundamentals("#{@ticker}?symbol=#{@ticker}#{type('balance-sheet')}#{period}")
|
|
22
|
+
end
|
|
23
|
+
def cashflow
|
|
24
|
+
fetch_fundamentals("#{@ticker}?symbol=#{@ticker}#{type('cash-flow')}#{period}")
|
|
25
|
+
end
|
|
26
|
+
def earnings
|
|
27
|
+
fetch_fundamentals("#{@ticker}?symbol=#{@ticker}#{type('financials')}#{period}")
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
def type(key)
|
|
32
|
+
series = FUNDAMENTALS[key.to_sym].map{|v| "#{@kind}#{v}"}.join(',')
|
|
33
|
+
"&type=#{series}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def period
|
|
37
|
+
start = years_ago(5).to_i
|
|
38
|
+
finish = years_ago(0).to_i
|
|
39
|
+
"&period1=#{start}&period2=#{finish}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def years_ago(d)
|
|
43
|
+
seconds_in_year = 24 * 60 * 60 * 365
|
|
44
|
+
Time.now - (d * seconds_in_year)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'oga'
|
|
2
|
+
|
|
3
|
+
class YaFinance
|
|
4
|
+
class Scrapper
|
|
5
|
+
class Calendar
|
|
6
|
+
def self.process(html)
|
|
7
|
+
doc = Oga.parse_xml(html)
|
|
8
|
+
response = []
|
|
9
|
+
doc.css('.simpTblRow').each do |line|
|
|
10
|
+
date = DateTime.parse line.css('[aria-label="Earnings Date"]').text
|
|
11
|
+
estimate = line.css('[aria-label="EPS Estimate"]').text
|
|
12
|
+
reported = line.css('[aria-label="Reported EPS"]').text
|
|
13
|
+
surprise = line.css('[aria-label="Surprise(%)"]').text
|
|
14
|
+
response.push({date: date, estimate: estimate, reported: reported, surprise: surprise })
|
|
15
|
+
end
|
|
16
|
+
response
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'oga'
|
|
2
|
+
|
|
3
|
+
class YaFinance
|
|
4
|
+
class Scrapper
|
|
5
|
+
class Holders
|
|
6
|
+
def self.process(html)
|
|
7
|
+
doc = Oga.parse_xml(html)
|
|
8
|
+
#TODO: organize result tables
|
|
9
|
+
holders = doc.css('[data-test] td').map{|e| e.text }
|
|
10
|
+
institutional = doc.css('.BdT td').map{|e| e.text } # 0
|
|
11
|
+
funds = doc.css('.BdT td').map{|e| e.text } # 1
|
|
12
|
+
{holders: holders, institutional: institutional, funds: funds}
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/ya_finance.rb
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http/persistent" # @TODO: how to remove?
|
|
4
|
+
require "net/http"
|
|
5
|
+
require "open-uri"
|
|
6
|
+
require "ostruct"
|
|
7
|
+
require "json"
|
|
8
|
+
require "csv"
|
|
9
|
+
require 'bigdecimal'
|
|
10
|
+
|
|
11
|
+
class YaFinance
|
|
12
|
+
VERSION = "0.0.1"
|
|
13
|
+
|
|
14
|
+
def initialize(ticker, options={})
|
|
15
|
+
@ticker = ticker
|
|
16
|
+
@options = options
|
|
17
|
+
end
|
|
18
|
+
def current; Current.new(@ticker, @options); end
|
|
19
|
+
def meta; Meta.new(@ticker, @options); end
|
|
20
|
+
def past; Past.new(@ticker, @options); end
|
|
21
|
+
def future; Future.new(@ticker, @options); end
|
|
22
|
+
|
|
23
|
+
def results(present); Results.new(@ticker, present, @options); end
|
|
24
|
+
def quarterly; Results.new(@ticker, 'quarterly', @options); end
|
|
25
|
+
def yearly; Results.new(@ticker, 'yearly', @options); end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Dir[File.join(__dir__, 'ya_finance', '*.rb')].each { |file| require file }
|
|
29
|
+
Dir[File.join(__dir__, 'ya_finance/scrapper', '*.rb')].each { |file| require file }
|
|
30
|
+
Dir[File.join(__dir__, 'ya_finance/insider_trading', '*.rb')].each { |file| require file }
|
metadata
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ya_finance
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Gabriel Fonseca Engel
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2023-08-10 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Financial Information consumer with CLI working in 2023
|
|
14
|
+
email: gabrielfengel@gmail.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions: []
|
|
17
|
+
extra_rdoc_files: []
|
|
18
|
+
files:
|
|
19
|
+
- Gemfile
|
|
20
|
+
- bin/yafin
|
|
21
|
+
- lib/ya_finance.rb
|
|
22
|
+
- lib/ya_finance/current.rb
|
|
23
|
+
- lib/ya_finance/format.rb
|
|
24
|
+
- lib/ya_finance/future.rb
|
|
25
|
+
- lib/ya_finance/http.rb
|
|
26
|
+
- lib/ya_finance/meta.rb
|
|
27
|
+
- lib/ya_finance/past.rb
|
|
28
|
+
- lib/ya_finance/results.rb
|
|
29
|
+
- lib/ya_finance/scrapper/calendar.rb
|
|
30
|
+
- lib/ya_finance/scrapper/holders.rb
|
|
31
|
+
homepage: https://rubygems.org/gems/ya_finance
|
|
32
|
+
licenses:
|
|
33
|
+
- MIT
|
|
34
|
+
metadata: {}
|
|
35
|
+
post_install_message:
|
|
36
|
+
rdoc_options: []
|
|
37
|
+
require_paths:
|
|
38
|
+
- lib
|
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
40
|
+
requirements:
|
|
41
|
+
- - ">="
|
|
42
|
+
- !ruby/object:Gem::Version
|
|
43
|
+
version: '0'
|
|
44
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
requirements: []
|
|
50
|
+
rubygems_version: 3.3.7
|
|
51
|
+
signing_key:
|
|
52
|
+
specification_version: 4
|
|
53
|
+
summary: Financial Information 2023
|
|
54
|
+
test_files: []
|