fin-ratios 0.1.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.
- package/dist/fetchers/edgar/index.cjs +100 -0
- package/dist/fetchers/edgar/index.cjs.map +1 -0
- package/dist/fetchers/edgar/index.d.cts +33 -0
- package/dist/fetchers/edgar/index.d.ts +33 -0
- package/dist/fetchers/edgar/index.js +98 -0
- package/dist/fetchers/edgar/index.js.map +1 -0
- package/dist/fetchers/fmp/index.cjs +110 -0
- package/dist/fetchers/fmp/index.cjs.map +1 -0
- package/dist/fetchers/fmp/index.d.cts +36 -0
- package/dist/fetchers/fmp/index.d.ts +36 -0
- package/dist/fetchers/fmp/index.js +107 -0
- package/dist/fetchers/fmp/index.js.map +1 -0
- package/dist/fetchers/yahoo/index.cjs +134 -0
- package/dist/fetchers/yahoo/index.cjs.map +1 -0
- package/dist/fetchers/yahoo/index.d.cts +50 -0
- package/dist/fetchers/yahoo/index.d.ts +50 -0
- package/dist/fetchers/yahoo/index.js +131 -0
- package/dist/fetchers/yahoo/index.js.map +1 -0
- package/dist/financials-DUHxWDPS.d.cts +113 -0
- package/dist/financials-DUHxWDPS.d.ts +113 -0
- package/dist/index.cjs +1180 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1314 -0
- package/dist/index.d.ts +1314 -0
- package/dist/index.js +1040 -0
- package/dist/index.js.map +1 -0
- package/dist/market-DlMw3vK1.d.cts +43 -0
- package/dist/market-DlMw3vK1.d.ts +43 -0
- package/package.json +87 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/fetchers/yahoo/index.ts
|
|
4
|
+
var BASE = "https://query1.finance.yahoo.com/v10/finance/quoteSummary";
|
|
5
|
+
var HEADERS = {
|
|
6
|
+
"User-Agent": "Mozilla/5.0 (compatible; fin-ratios/0.1)",
|
|
7
|
+
"Accept": "application/json"
|
|
8
|
+
};
|
|
9
|
+
async function fetchYahoo(ticker, options = {}) {
|
|
10
|
+
const modules = [
|
|
11
|
+
"financialData",
|
|
12
|
+
"defaultKeyStatistics",
|
|
13
|
+
"summaryDetail",
|
|
14
|
+
"assetProfile",
|
|
15
|
+
"incomeStatementHistory",
|
|
16
|
+
"balanceSheetHistory",
|
|
17
|
+
"cashflowStatementHistory",
|
|
18
|
+
...options.modules ?? []
|
|
19
|
+
].join(",");
|
|
20
|
+
const url = `${BASE}/${encodeURIComponent(ticker)}?modules=${modules}`;
|
|
21
|
+
const resp = await fetch(url, { headers: HEADERS });
|
|
22
|
+
if (!resp.ok) {
|
|
23
|
+
throw new Error(`Yahoo Finance request failed: ${resp.status} for ${ticker}`);
|
|
24
|
+
}
|
|
25
|
+
const json = await resp.json();
|
|
26
|
+
const result = json?.quoteSummary?.result?.[0];
|
|
27
|
+
if (!result) {
|
|
28
|
+
throw new Error(`No data returned for ${ticker}`);
|
|
29
|
+
}
|
|
30
|
+
const fd = result.financialData ?? {};
|
|
31
|
+
const ks = result.defaultKeyStatistics ?? {};
|
|
32
|
+
const sd = result.summaryDetail ?? {};
|
|
33
|
+
const ap = result.assetProfile ?? {};
|
|
34
|
+
const inc = result.incomeStatementHistory?.incomeStatementHistory?.[0] ?? {};
|
|
35
|
+
const bal = result.balanceSheetHistory?.balanceSheetHistory?.[0] ?? {};
|
|
36
|
+
const cf = result.cashflowStatementHistory?.cashflowStatementHistory?.[0] ?? {};
|
|
37
|
+
const price = _n(fd.currentPrice) ?? _n(fd.regularMarketPrice) ?? 0;
|
|
38
|
+
const marketCap = _n(ks.marketCap) ?? 0;
|
|
39
|
+
const shares = _n(ks.sharesOutstanding) ?? 0;
|
|
40
|
+
const base = {
|
|
41
|
+
marketData: {
|
|
42
|
+
price,
|
|
43
|
+
marketCap,
|
|
44
|
+
sharesOutstanding: shares,
|
|
45
|
+
enterpriseValue: _n(ks.enterpriseValue),
|
|
46
|
+
forwardEps: _n(ks.forwardEps),
|
|
47
|
+
trailingEps: _n(ks.trailingEps),
|
|
48
|
+
dividendPerShare: _n(sd.dividendRate),
|
|
49
|
+
ticker
|
|
50
|
+
},
|
|
51
|
+
income: {
|
|
52
|
+
revenue: _n(inc.totalRevenue) ?? _n(fd.totalRevenue) ?? 0,
|
|
53
|
+
grossProfit: _n(inc.grossProfit) ?? 0,
|
|
54
|
+
cogs: (_n(inc.totalRevenue) ?? 0) - (_n(inc.grossProfit) ?? 0),
|
|
55
|
+
ebit: _n(inc.ebit) ?? _n(fd.operatingCashflow) ?? 0,
|
|
56
|
+
ebitda: _n(fd.ebitda) ?? 0,
|
|
57
|
+
netIncome: _n(inc.netIncome) ?? _n(fd.netIncomeToCommon) ?? 0,
|
|
58
|
+
interestExpense: Math.abs(_n(inc.interestExpense) ?? 0),
|
|
59
|
+
incomeTaxExpense: _n(inc.incomeTaxExpense) ?? 0,
|
|
60
|
+
ebt: _n(inc.pretaxIncome) ?? 0,
|
|
61
|
+
depreciationAndAmortization: 0,
|
|
62
|
+
// Not available in this module
|
|
63
|
+
sharesOutstanding: shares,
|
|
64
|
+
eps: _n(ks.trailingEps)
|
|
65
|
+
},
|
|
66
|
+
balance: {
|
|
67
|
+
totalAssets: _n(bal.totalAssets) ?? 0,
|
|
68
|
+
currentAssets: _n(bal.totalCurrentAssets) ?? 0,
|
|
69
|
+
cash: _n(bal.cash) ?? _n(fd.totalCash) ?? 0,
|
|
70
|
+
shortTermInvestments: _n(bal.shortTermInvestments),
|
|
71
|
+
accountsReceivable: _n(bal.netReceivables) ?? 0,
|
|
72
|
+
inventory: _n(bal.inventory) ?? 0,
|
|
73
|
+
netPPE: _n(bal.propertyPlantEquipment) ?? 0,
|
|
74
|
+
goodwill: _n(bal.goodWill),
|
|
75
|
+
intangibleAssets: _n(bal.intangibleAssets),
|
|
76
|
+
retainedEarnings: _n(bal.retainedEarnings) ?? 0,
|
|
77
|
+
totalLiabilities: _n(bal.totalLiab) ?? 0,
|
|
78
|
+
currentLiabilities: _n(bal.totalCurrentLiabilities) ?? 0,
|
|
79
|
+
accountsPayable: _n(bal.accountsPayable) ?? 0,
|
|
80
|
+
shortTermDebt: _n(bal.shortLongTermDebt),
|
|
81
|
+
longTermDebt: _n(bal.longTermDebt) ?? _n(fd.totalDebt) ?? 0,
|
|
82
|
+
totalDebt: _n(fd.totalDebt) ?? 0,
|
|
83
|
+
totalEquity: _n(bal.totalStockholderEquity) ?? 0,
|
|
84
|
+
sharesOutstanding: shares
|
|
85
|
+
},
|
|
86
|
+
cashFlow: {
|
|
87
|
+
operatingCashFlow: _n(cf.totalCashFromOperatingActivities) ?? _n(fd.operatingCashflow) ?? 0,
|
|
88
|
+
capex: Math.abs(_n(cf.capitalExpenditures) ?? 0),
|
|
89
|
+
investingCashFlow: _n(cf.totalCashflowsFromInvestingActivities),
|
|
90
|
+
financingCashFlow: _n(cf.totalCashFromFinancingActivities),
|
|
91
|
+
dividendsPaid: _n(cf.dividendsPaid),
|
|
92
|
+
stockBasedCompensation: _n(cf.stockBasedCompensation)
|
|
93
|
+
},
|
|
94
|
+
sector: ap.sector,
|
|
95
|
+
industry: ap.industry
|
|
96
|
+
};
|
|
97
|
+
const empCount = _n(ap.fullTimeEmployees);
|
|
98
|
+
if (empCount != null) base.employeeCount = empCount;
|
|
99
|
+
const betaVal = _n(ks.beta);
|
|
100
|
+
if (betaVal != null) base.beta = betaVal;
|
|
101
|
+
const divYield = _n(sd.dividendYield);
|
|
102
|
+
if (divYield != null) base.dividendYield = divYield;
|
|
103
|
+
return base;
|
|
104
|
+
}
|
|
105
|
+
async function fetchPriceHistory(ticker, period = "1y") {
|
|
106
|
+
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(ticker)}?range=${period}&interval=1d`;
|
|
107
|
+
const resp = await fetch(url, { headers: HEADERS });
|
|
108
|
+
if (!resp.ok) throw new Error(`Price history request failed for ${ticker}`);
|
|
109
|
+
const json = await resp.json();
|
|
110
|
+
const chart = json?.chart?.result?.[0];
|
|
111
|
+
if (!chart) throw new Error(`No price data for ${ticker}`);
|
|
112
|
+
const timestamps = chart.timestamp ?? [];
|
|
113
|
+
const closes = chart.indicators?.quote?.[0]?.close ?? [];
|
|
114
|
+
const dates = [];
|
|
115
|
+
const prices = [];
|
|
116
|
+
for (let i = 0; i < timestamps.length; i++) {
|
|
117
|
+
if (closes[i] != null) {
|
|
118
|
+
dates.push(new Date((timestamps[i] ?? 0) * 1e3).toISOString().split("T")[0]);
|
|
119
|
+
prices.push(closes[i]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { dates, prices };
|
|
123
|
+
}
|
|
124
|
+
function _n(v) {
|
|
125
|
+
if (v == null) return null;
|
|
126
|
+
const raw = typeof v === "object" ? v.raw ?? v : v;
|
|
127
|
+
const n = Number(raw);
|
|
128
|
+
return isNaN(n) ? null : n;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
exports.fetchPriceHistory = fetchPriceHistory;
|
|
132
|
+
exports.fetchYahoo = fetchYahoo;
|
|
133
|
+
//# sourceMappingURL=index.cjs.map
|
|
134
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fetchers/yahoo/index.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Yahoo Finance fetcher — free, no API key required.\n * Uses Yahoo Finance's public JSON endpoints.\n *\n * For production use, consider using the `yahoo-finance2` npm package instead:\n * npm install yahoo-finance2\n *\n * Rate limit: ~2,000 requests/hour (unofficial). Add delays for bulk requests.\n */\n\nimport type {\n IncomeStatement,\n BalanceSheet,\n CashFlowStatement,\n MarketData,\n} from '../../types/index.js'\n\nconst BASE = 'https://query1.finance.yahoo.com/v10/finance/quoteSummary'\nconst HEADERS = {\n 'User-Agent': 'Mozilla/5.0 (compatible; fin-ratios/0.1)',\n 'Accept': 'application/json',\n}\n\nexport interface YahooFetchOptions {\n /** Additional modules to include (default covers all financial statements) */\n modules?: string[]\n}\n\nexport interface YahooData {\n marketData: MarketData\n income: IncomeStatement\n balance: BalanceSheet\n cashFlow: CashFlowStatement\n sector?: string\n industry?: string\n employeeCount?: number\n beta?: number\n dividendYield?: number\n}\n\n/**\n * Fetch comprehensive financial data for a stock ticker from Yahoo Finance.\n *\n * @example\n * const data = await fetchYahoo('AAPL')\n * const ratio = pe({ marketCap: data.marketData.marketCap, netIncome: data.income.netIncome })\n */\nexport async function fetchYahoo(\n ticker: string,\n options: YahooFetchOptions = {}\n): Promise<YahooData> {\n const modules = [\n 'financialData',\n 'defaultKeyStatistics',\n 'summaryDetail',\n 'assetProfile',\n 'incomeStatementHistory',\n 'balanceSheetHistory',\n 'cashflowStatementHistory',\n ...(options.modules ?? []),\n ].join(',')\n\n const url = `${BASE}/${encodeURIComponent(ticker)}?modules=${modules}`\n\n const resp = await fetch(url, { headers: HEADERS })\n if (!resp.ok) {\n throw new Error(`Yahoo Finance request failed: ${resp.status} for ${ticker}`)\n }\n\n const json = (await resp.json()) as Record<string, unknown>\n const result = (json?.quoteSummary as any)?.result?.[0]\n if (!result) {\n throw new Error(`No data returned for ${ticker}`)\n }\n\n const fd = result.financialData ?? {}\n const ks = result.defaultKeyStatistics ?? {}\n const sd = result.summaryDetail ?? {}\n const ap = result.assetProfile ?? {}\n\n // Income statement (TTM)\n const inc = result.incomeStatementHistory?.incomeStatementHistory?.[0] ?? {}\n // Balance sheet (most recent quarter/year)\n const bal = result.balanceSheetHistory?.balanceSheetHistory?.[0] ?? {}\n // Cash flow (most recent)\n const cf = result.cashflowStatementHistory?.cashflowStatementHistory?.[0] ?? {}\n\n const price = _n(fd.currentPrice) ?? _n(fd.regularMarketPrice) ?? 0\n const marketCap = _n(ks.marketCap) ?? 0\n const shares = _n(ks.sharesOutstanding) ?? 0\n\n const base: YahooData = {\n marketData: {\n price,\n marketCap,\n sharesOutstanding: shares,\n enterpriseValue: _n(ks.enterpriseValue),\n forwardEps: _n(ks.forwardEps),\n trailingEps: _n(ks.trailingEps),\n dividendPerShare: _n(sd.dividendRate),\n ticker,\n },\n income: {\n revenue: _n(inc.totalRevenue) ?? _n(fd.totalRevenue) ?? 0,\n grossProfit: _n(inc.grossProfit) ?? 0,\n cogs: (_n(inc.totalRevenue) ?? 0) - (_n(inc.grossProfit) ?? 0),\n ebit: _n(inc.ebit) ?? _n(fd.operatingCashflow) ?? 0,\n ebitda: _n(fd.ebitda) ?? 0,\n netIncome: _n(inc.netIncome) ?? _n(fd.netIncomeToCommon) ?? 0,\n interestExpense: Math.abs(_n(inc.interestExpense) ?? 0),\n incomeTaxExpense: _n(inc.incomeTaxExpense) ?? 0,\n ebt: _n(inc.pretaxIncome) ?? 0,\n depreciationAndAmortization: 0, // Not available in this module\n sharesOutstanding: shares,\n eps: _n(ks.trailingEps),\n },\n balance: {\n totalAssets: _n(bal.totalAssets) ?? 0,\n currentAssets: _n(bal.totalCurrentAssets) ?? 0,\n cash: _n(bal.cash) ?? _n(fd.totalCash) ?? 0,\n shortTermInvestments: _n(bal.shortTermInvestments),\n accountsReceivable: _n(bal.netReceivables) ?? 0,\n inventory: _n(bal.inventory) ?? 0,\n netPPE: _n(bal.propertyPlantEquipment) ?? 0,\n goodwill: _n(bal.goodWill),\n intangibleAssets: _n(bal.intangibleAssets),\n retainedEarnings: _n(bal.retainedEarnings) ?? 0,\n totalLiabilities: _n(bal.totalLiab) ?? 0,\n currentLiabilities: _n(bal.totalCurrentLiabilities) ?? 0,\n accountsPayable: _n(bal.accountsPayable) ?? 0,\n shortTermDebt: _n(bal.shortLongTermDebt),\n longTermDebt: _n(bal.longTermDebt) ?? _n(fd.totalDebt) ?? 0,\n totalDebt: _n(fd.totalDebt) ?? 0,\n totalEquity: _n(bal.totalStockholderEquity) ?? 0,\n sharesOutstanding: shares,\n },\n cashFlow: {\n operatingCashFlow: _n(cf.totalCashFromOperatingActivities) ?? _n(fd.operatingCashflow) ?? 0,\n capex: Math.abs(_n(cf.capitalExpenditures) ?? 0),\n investingCashFlow: _n(cf.totalCashflowsFromInvestingActivities),\n financingCashFlow: _n(cf.totalCashFromFinancingActivities),\n dividendsPaid: _n(cf.dividendsPaid),\n stockBasedCompensation: _n(cf.stockBasedCompensation),\n },\n sector: ap.sector,\n industry: ap.industry,\n }\n const empCount = _n(ap.fullTimeEmployees); if (empCount != null) base.employeeCount = empCount\n const betaVal = _n(ks.beta); if (betaVal != null) base.beta = betaVal\n const divYield = _n(sd.dividendYield); if (divYield != null) base.dividendYield = divYield\n return base\n}\n\n/**\n * Fetch price history (daily close prices) for risk calculations.\n *\n * @example\n * const prices = await fetchPriceHistory('AAPL', '1y')\n * const returns = pricesToReturns(prices)\n * const sharpe = sharpeRatio({ returns, riskFreeRate: 0.05 })\n */\nexport async function fetchPriceHistory(\n ticker: string,\n period: '1mo' | '3mo' | '6mo' | '1y' | '2y' | '5y' | 'max' = '1y'\n): Promise<{ dates: string[]; prices: number[] }> {\n const url = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(ticker)}?range=${period}&interval=1d`\n const resp = await fetch(url, { headers: HEADERS })\n if (!resp.ok) throw new Error(`Price history request failed for ${ticker}`)\n\n const json = (await resp.json()) as any\n const chart = json?.chart?.result?.[0]\n if (!chart) throw new Error(`No price data for ${ticker}`)\n\n const timestamps: number[] = chart.timestamp ?? []\n const closes: number[] = chart.indicators?.quote?.[0]?.close ?? []\n\n const dates: string[] = []\n const prices: number[] = []\n\n for (let i = 0; i < timestamps.length; i++) {\n if (closes[i] != null) {\n dates.push(new Date((timestamps[i] ?? 0) * 1000).toISOString().split('T')[0]!)\n prices.push(closes[i] as number)\n }\n }\n\n return { dates, prices }\n}\n\nfunction _n(v: unknown): number | null {\n if (v == null) return null\n const raw = typeof v === 'object' ? (v as any).raw ?? v : v\n const n = Number(raw)\n return isNaN(n) ? null : n\n}\n"]}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { I as IncomeStatement, B as BalanceSheet, C as CashFlowStatement } from '../../financials-DUHxWDPS.cjs';
|
|
2
|
+
import { M as MarketData } from '../../market-DlMw3vK1.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Yahoo Finance fetcher — free, no API key required.
|
|
6
|
+
* Uses Yahoo Finance's public JSON endpoints.
|
|
7
|
+
*
|
|
8
|
+
* For production use, consider using the `yahoo-finance2` npm package instead:
|
|
9
|
+
* npm install yahoo-finance2
|
|
10
|
+
*
|
|
11
|
+
* Rate limit: ~2,000 requests/hour (unofficial). Add delays for bulk requests.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
interface YahooFetchOptions {
|
|
15
|
+
/** Additional modules to include (default covers all financial statements) */
|
|
16
|
+
modules?: string[];
|
|
17
|
+
}
|
|
18
|
+
interface YahooData {
|
|
19
|
+
marketData: MarketData;
|
|
20
|
+
income: IncomeStatement;
|
|
21
|
+
balance: BalanceSheet;
|
|
22
|
+
cashFlow: CashFlowStatement;
|
|
23
|
+
sector?: string;
|
|
24
|
+
industry?: string;
|
|
25
|
+
employeeCount?: number;
|
|
26
|
+
beta?: number;
|
|
27
|
+
dividendYield?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fetch comprehensive financial data for a stock ticker from Yahoo Finance.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const data = await fetchYahoo('AAPL')
|
|
34
|
+
* const ratio = pe({ marketCap: data.marketData.marketCap, netIncome: data.income.netIncome })
|
|
35
|
+
*/
|
|
36
|
+
declare function fetchYahoo(ticker: string, options?: YahooFetchOptions): Promise<YahooData>;
|
|
37
|
+
/**
|
|
38
|
+
* Fetch price history (daily close prices) for risk calculations.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const prices = await fetchPriceHistory('AAPL', '1y')
|
|
42
|
+
* const returns = pricesToReturns(prices)
|
|
43
|
+
* const sharpe = sharpeRatio({ returns, riskFreeRate: 0.05 })
|
|
44
|
+
*/
|
|
45
|
+
declare function fetchPriceHistory(ticker: string, period?: '1mo' | '3mo' | '6mo' | '1y' | '2y' | '5y' | 'max'): Promise<{
|
|
46
|
+
dates: string[];
|
|
47
|
+
prices: number[];
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
export { type YahooData, type YahooFetchOptions, fetchPriceHistory, fetchYahoo };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { I as IncomeStatement, B as BalanceSheet, C as CashFlowStatement } from '../../financials-DUHxWDPS.js';
|
|
2
|
+
import { M as MarketData } from '../../market-DlMw3vK1.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Yahoo Finance fetcher — free, no API key required.
|
|
6
|
+
* Uses Yahoo Finance's public JSON endpoints.
|
|
7
|
+
*
|
|
8
|
+
* For production use, consider using the `yahoo-finance2` npm package instead:
|
|
9
|
+
* npm install yahoo-finance2
|
|
10
|
+
*
|
|
11
|
+
* Rate limit: ~2,000 requests/hour (unofficial). Add delays for bulk requests.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
interface YahooFetchOptions {
|
|
15
|
+
/** Additional modules to include (default covers all financial statements) */
|
|
16
|
+
modules?: string[];
|
|
17
|
+
}
|
|
18
|
+
interface YahooData {
|
|
19
|
+
marketData: MarketData;
|
|
20
|
+
income: IncomeStatement;
|
|
21
|
+
balance: BalanceSheet;
|
|
22
|
+
cashFlow: CashFlowStatement;
|
|
23
|
+
sector?: string;
|
|
24
|
+
industry?: string;
|
|
25
|
+
employeeCount?: number;
|
|
26
|
+
beta?: number;
|
|
27
|
+
dividendYield?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Fetch comprehensive financial data for a stock ticker from Yahoo Finance.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const data = await fetchYahoo('AAPL')
|
|
34
|
+
* const ratio = pe({ marketCap: data.marketData.marketCap, netIncome: data.income.netIncome })
|
|
35
|
+
*/
|
|
36
|
+
declare function fetchYahoo(ticker: string, options?: YahooFetchOptions): Promise<YahooData>;
|
|
37
|
+
/**
|
|
38
|
+
* Fetch price history (daily close prices) for risk calculations.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* const prices = await fetchPriceHistory('AAPL', '1y')
|
|
42
|
+
* const returns = pricesToReturns(prices)
|
|
43
|
+
* const sharpe = sharpeRatio({ returns, riskFreeRate: 0.05 })
|
|
44
|
+
*/
|
|
45
|
+
declare function fetchPriceHistory(ticker: string, period?: '1mo' | '3mo' | '6mo' | '1y' | '2y' | '5y' | 'max'): Promise<{
|
|
46
|
+
dates: string[];
|
|
47
|
+
prices: number[];
|
|
48
|
+
}>;
|
|
49
|
+
|
|
50
|
+
export { type YahooData, type YahooFetchOptions, fetchPriceHistory, fetchYahoo };
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// src/fetchers/yahoo/index.ts
|
|
2
|
+
var BASE = "https://query1.finance.yahoo.com/v10/finance/quoteSummary";
|
|
3
|
+
var HEADERS = {
|
|
4
|
+
"User-Agent": "Mozilla/5.0 (compatible; fin-ratios/0.1)",
|
|
5
|
+
"Accept": "application/json"
|
|
6
|
+
};
|
|
7
|
+
async function fetchYahoo(ticker, options = {}) {
|
|
8
|
+
const modules = [
|
|
9
|
+
"financialData",
|
|
10
|
+
"defaultKeyStatistics",
|
|
11
|
+
"summaryDetail",
|
|
12
|
+
"assetProfile",
|
|
13
|
+
"incomeStatementHistory",
|
|
14
|
+
"balanceSheetHistory",
|
|
15
|
+
"cashflowStatementHistory",
|
|
16
|
+
...options.modules ?? []
|
|
17
|
+
].join(",");
|
|
18
|
+
const url = `${BASE}/${encodeURIComponent(ticker)}?modules=${modules}`;
|
|
19
|
+
const resp = await fetch(url, { headers: HEADERS });
|
|
20
|
+
if (!resp.ok) {
|
|
21
|
+
throw new Error(`Yahoo Finance request failed: ${resp.status} for ${ticker}`);
|
|
22
|
+
}
|
|
23
|
+
const json = await resp.json();
|
|
24
|
+
const result = json?.quoteSummary?.result?.[0];
|
|
25
|
+
if (!result) {
|
|
26
|
+
throw new Error(`No data returned for ${ticker}`);
|
|
27
|
+
}
|
|
28
|
+
const fd = result.financialData ?? {};
|
|
29
|
+
const ks = result.defaultKeyStatistics ?? {};
|
|
30
|
+
const sd = result.summaryDetail ?? {};
|
|
31
|
+
const ap = result.assetProfile ?? {};
|
|
32
|
+
const inc = result.incomeStatementHistory?.incomeStatementHistory?.[0] ?? {};
|
|
33
|
+
const bal = result.balanceSheetHistory?.balanceSheetHistory?.[0] ?? {};
|
|
34
|
+
const cf = result.cashflowStatementHistory?.cashflowStatementHistory?.[0] ?? {};
|
|
35
|
+
const price = _n(fd.currentPrice) ?? _n(fd.regularMarketPrice) ?? 0;
|
|
36
|
+
const marketCap = _n(ks.marketCap) ?? 0;
|
|
37
|
+
const shares = _n(ks.sharesOutstanding) ?? 0;
|
|
38
|
+
const base = {
|
|
39
|
+
marketData: {
|
|
40
|
+
price,
|
|
41
|
+
marketCap,
|
|
42
|
+
sharesOutstanding: shares,
|
|
43
|
+
enterpriseValue: _n(ks.enterpriseValue),
|
|
44
|
+
forwardEps: _n(ks.forwardEps),
|
|
45
|
+
trailingEps: _n(ks.trailingEps),
|
|
46
|
+
dividendPerShare: _n(sd.dividendRate),
|
|
47
|
+
ticker
|
|
48
|
+
},
|
|
49
|
+
income: {
|
|
50
|
+
revenue: _n(inc.totalRevenue) ?? _n(fd.totalRevenue) ?? 0,
|
|
51
|
+
grossProfit: _n(inc.grossProfit) ?? 0,
|
|
52
|
+
cogs: (_n(inc.totalRevenue) ?? 0) - (_n(inc.grossProfit) ?? 0),
|
|
53
|
+
ebit: _n(inc.ebit) ?? _n(fd.operatingCashflow) ?? 0,
|
|
54
|
+
ebitda: _n(fd.ebitda) ?? 0,
|
|
55
|
+
netIncome: _n(inc.netIncome) ?? _n(fd.netIncomeToCommon) ?? 0,
|
|
56
|
+
interestExpense: Math.abs(_n(inc.interestExpense) ?? 0),
|
|
57
|
+
incomeTaxExpense: _n(inc.incomeTaxExpense) ?? 0,
|
|
58
|
+
ebt: _n(inc.pretaxIncome) ?? 0,
|
|
59
|
+
depreciationAndAmortization: 0,
|
|
60
|
+
// Not available in this module
|
|
61
|
+
sharesOutstanding: shares,
|
|
62
|
+
eps: _n(ks.trailingEps)
|
|
63
|
+
},
|
|
64
|
+
balance: {
|
|
65
|
+
totalAssets: _n(bal.totalAssets) ?? 0,
|
|
66
|
+
currentAssets: _n(bal.totalCurrentAssets) ?? 0,
|
|
67
|
+
cash: _n(bal.cash) ?? _n(fd.totalCash) ?? 0,
|
|
68
|
+
shortTermInvestments: _n(bal.shortTermInvestments),
|
|
69
|
+
accountsReceivable: _n(bal.netReceivables) ?? 0,
|
|
70
|
+
inventory: _n(bal.inventory) ?? 0,
|
|
71
|
+
netPPE: _n(bal.propertyPlantEquipment) ?? 0,
|
|
72
|
+
goodwill: _n(bal.goodWill),
|
|
73
|
+
intangibleAssets: _n(bal.intangibleAssets),
|
|
74
|
+
retainedEarnings: _n(bal.retainedEarnings) ?? 0,
|
|
75
|
+
totalLiabilities: _n(bal.totalLiab) ?? 0,
|
|
76
|
+
currentLiabilities: _n(bal.totalCurrentLiabilities) ?? 0,
|
|
77
|
+
accountsPayable: _n(bal.accountsPayable) ?? 0,
|
|
78
|
+
shortTermDebt: _n(bal.shortLongTermDebt),
|
|
79
|
+
longTermDebt: _n(bal.longTermDebt) ?? _n(fd.totalDebt) ?? 0,
|
|
80
|
+
totalDebt: _n(fd.totalDebt) ?? 0,
|
|
81
|
+
totalEquity: _n(bal.totalStockholderEquity) ?? 0,
|
|
82
|
+
sharesOutstanding: shares
|
|
83
|
+
},
|
|
84
|
+
cashFlow: {
|
|
85
|
+
operatingCashFlow: _n(cf.totalCashFromOperatingActivities) ?? _n(fd.operatingCashflow) ?? 0,
|
|
86
|
+
capex: Math.abs(_n(cf.capitalExpenditures) ?? 0),
|
|
87
|
+
investingCashFlow: _n(cf.totalCashflowsFromInvestingActivities),
|
|
88
|
+
financingCashFlow: _n(cf.totalCashFromFinancingActivities),
|
|
89
|
+
dividendsPaid: _n(cf.dividendsPaid),
|
|
90
|
+
stockBasedCompensation: _n(cf.stockBasedCompensation)
|
|
91
|
+
},
|
|
92
|
+
sector: ap.sector,
|
|
93
|
+
industry: ap.industry
|
|
94
|
+
};
|
|
95
|
+
const empCount = _n(ap.fullTimeEmployees);
|
|
96
|
+
if (empCount != null) base.employeeCount = empCount;
|
|
97
|
+
const betaVal = _n(ks.beta);
|
|
98
|
+
if (betaVal != null) base.beta = betaVal;
|
|
99
|
+
const divYield = _n(sd.dividendYield);
|
|
100
|
+
if (divYield != null) base.dividendYield = divYield;
|
|
101
|
+
return base;
|
|
102
|
+
}
|
|
103
|
+
async function fetchPriceHistory(ticker, period = "1y") {
|
|
104
|
+
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(ticker)}?range=${period}&interval=1d`;
|
|
105
|
+
const resp = await fetch(url, { headers: HEADERS });
|
|
106
|
+
if (!resp.ok) throw new Error(`Price history request failed for ${ticker}`);
|
|
107
|
+
const json = await resp.json();
|
|
108
|
+
const chart = json?.chart?.result?.[0];
|
|
109
|
+
if (!chart) throw new Error(`No price data for ${ticker}`);
|
|
110
|
+
const timestamps = chart.timestamp ?? [];
|
|
111
|
+
const closes = chart.indicators?.quote?.[0]?.close ?? [];
|
|
112
|
+
const dates = [];
|
|
113
|
+
const prices = [];
|
|
114
|
+
for (let i = 0; i < timestamps.length; i++) {
|
|
115
|
+
if (closes[i] != null) {
|
|
116
|
+
dates.push(new Date((timestamps[i] ?? 0) * 1e3).toISOString().split("T")[0]);
|
|
117
|
+
prices.push(closes[i]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { dates, prices };
|
|
121
|
+
}
|
|
122
|
+
function _n(v) {
|
|
123
|
+
if (v == null) return null;
|
|
124
|
+
const raw = typeof v === "object" ? v.raw ?? v : v;
|
|
125
|
+
const n = Number(raw);
|
|
126
|
+
return isNaN(n) ? null : n;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { fetchPriceHistory, fetchYahoo };
|
|
130
|
+
//# sourceMappingURL=index.js.map
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fetchers/yahoo/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Yahoo Finance fetcher — free, no API key required.\n * Uses Yahoo Finance's public JSON endpoints.\n *\n * For production use, consider using the `yahoo-finance2` npm package instead:\n * npm install yahoo-finance2\n *\n * Rate limit: ~2,000 requests/hour (unofficial). Add delays for bulk requests.\n */\n\nimport type {\n IncomeStatement,\n BalanceSheet,\n CashFlowStatement,\n MarketData,\n} from '../../types/index.js'\n\nconst BASE = 'https://query1.finance.yahoo.com/v10/finance/quoteSummary'\nconst HEADERS = {\n 'User-Agent': 'Mozilla/5.0 (compatible; fin-ratios/0.1)',\n 'Accept': 'application/json',\n}\n\nexport interface YahooFetchOptions {\n /** Additional modules to include (default covers all financial statements) */\n modules?: string[]\n}\n\nexport interface YahooData {\n marketData: MarketData\n income: IncomeStatement\n balance: BalanceSheet\n cashFlow: CashFlowStatement\n sector?: string\n industry?: string\n employeeCount?: number\n beta?: number\n dividendYield?: number\n}\n\n/**\n * Fetch comprehensive financial data for a stock ticker from Yahoo Finance.\n *\n * @example\n * const data = await fetchYahoo('AAPL')\n * const ratio = pe({ marketCap: data.marketData.marketCap, netIncome: data.income.netIncome })\n */\nexport async function fetchYahoo(\n ticker: string,\n options: YahooFetchOptions = {}\n): Promise<YahooData> {\n const modules = [\n 'financialData',\n 'defaultKeyStatistics',\n 'summaryDetail',\n 'assetProfile',\n 'incomeStatementHistory',\n 'balanceSheetHistory',\n 'cashflowStatementHistory',\n ...(options.modules ?? []),\n ].join(',')\n\n const url = `${BASE}/${encodeURIComponent(ticker)}?modules=${modules}`\n\n const resp = await fetch(url, { headers: HEADERS })\n if (!resp.ok) {\n throw new Error(`Yahoo Finance request failed: ${resp.status} for ${ticker}`)\n }\n\n const json = (await resp.json()) as Record<string, unknown>\n const result = (json?.quoteSummary as any)?.result?.[0]\n if (!result) {\n throw new Error(`No data returned for ${ticker}`)\n }\n\n const fd = result.financialData ?? {}\n const ks = result.defaultKeyStatistics ?? {}\n const sd = result.summaryDetail ?? {}\n const ap = result.assetProfile ?? {}\n\n // Income statement (TTM)\n const inc = result.incomeStatementHistory?.incomeStatementHistory?.[0] ?? {}\n // Balance sheet (most recent quarter/year)\n const bal = result.balanceSheetHistory?.balanceSheetHistory?.[0] ?? {}\n // Cash flow (most recent)\n const cf = result.cashflowStatementHistory?.cashflowStatementHistory?.[0] ?? {}\n\n const price = _n(fd.currentPrice) ?? _n(fd.regularMarketPrice) ?? 0\n const marketCap = _n(ks.marketCap) ?? 0\n const shares = _n(ks.sharesOutstanding) ?? 0\n\n const base: YahooData = {\n marketData: {\n price,\n marketCap,\n sharesOutstanding: shares,\n enterpriseValue: _n(ks.enterpriseValue),\n forwardEps: _n(ks.forwardEps),\n trailingEps: _n(ks.trailingEps),\n dividendPerShare: _n(sd.dividendRate),\n ticker,\n },\n income: {\n revenue: _n(inc.totalRevenue) ?? _n(fd.totalRevenue) ?? 0,\n grossProfit: _n(inc.grossProfit) ?? 0,\n cogs: (_n(inc.totalRevenue) ?? 0) - (_n(inc.grossProfit) ?? 0),\n ebit: _n(inc.ebit) ?? _n(fd.operatingCashflow) ?? 0,\n ebitda: _n(fd.ebitda) ?? 0,\n netIncome: _n(inc.netIncome) ?? _n(fd.netIncomeToCommon) ?? 0,\n interestExpense: Math.abs(_n(inc.interestExpense) ?? 0),\n incomeTaxExpense: _n(inc.incomeTaxExpense) ?? 0,\n ebt: _n(inc.pretaxIncome) ?? 0,\n depreciationAndAmortization: 0, // Not available in this module\n sharesOutstanding: shares,\n eps: _n(ks.trailingEps),\n },\n balance: {\n totalAssets: _n(bal.totalAssets) ?? 0,\n currentAssets: _n(bal.totalCurrentAssets) ?? 0,\n cash: _n(bal.cash) ?? _n(fd.totalCash) ?? 0,\n shortTermInvestments: _n(bal.shortTermInvestments),\n accountsReceivable: _n(bal.netReceivables) ?? 0,\n inventory: _n(bal.inventory) ?? 0,\n netPPE: _n(bal.propertyPlantEquipment) ?? 0,\n goodwill: _n(bal.goodWill),\n intangibleAssets: _n(bal.intangibleAssets),\n retainedEarnings: _n(bal.retainedEarnings) ?? 0,\n totalLiabilities: _n(bal.totalLiab) ?? 0,\n currentLiabilities: _n(bal.totalCurrentLiabilities) ?? 0,\n accountsPayable: _n(bal.accountsPayable) ?? 0,\n shortTermDebt: _n(bal.shortLongTermDebt),\n longTermDebt: _n(bal.longTermDebt) ?? _n(fd.totalDebt) ?? 0,\n totalDebt: _n(fd.totalDebt) ?? 0,\n totalEquity: _n(bal.totalStockholderEquity) ?? 0,\n sharesOutstanding: shares,\n },\n cashFlow: {\n operatingCashFlow: _n(cf.totalCashFromOperatingActivities) ?? _n(fd.operatingCashflow) ?? 0,\n capex: Math.abs(_n(cf.capitalExpenditures) ?? 0),\n investingCashFlow: _n(cf.totalCashflowsFromInvestingActivities),\n financingCashFlow: _n(cf.totalCashFromFinancingActivities),\n dividendsPaid: _n(cf.dividendsPaid),\n stockBasedCompensation: _n(cf.stockBasedCompensation),\n },\n sector: ap.sector,\n industry: ap.industry,\n }\n const empCount = _n(ap.fullTimeEmployees); if (empCount != null) base.employeeCount = empCount\n const betaVal = _n(ks.beta); if (betaVal != null) base.beta = betaVal\n const divYield = _n(sd.dividendYield); if (divYield != null) base.dividendYield = divYield\n return base\n}\n\n/**\n * Fetch price history (daily close prices) for risk calculations.\n *\n * @example\n * const prices = await fetchPriceHistory('AAPL', '1y')\n * const returns = pricesToReturns(prices)\n * const sharpe = sharpeRatio({ returns, riskFreeRate: 0.05 })\n */\nexport async function fetchPriceHistory(\n ticker: string,\n period: '1mo' | '3mo' | '6mo' | '1y' | '2y' | '5y' | 'max' = '1y'\n): Promise<{ dates: string[]; prices: number[] }> {\n const url = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(ticker)}?range=${period}&interval=1d`\n const resp = await fetch(url, { headers: HEADERS })\n if (!resp.ok) throw new Error(`Price history request failed for ${ticker}`)\n\n const json = (await resp.json()) as any\n const chart = json?.chart?.result?.[0]\n if (!chart) throw new Error(`No price data for ${ticker}`)\n\n const timestamps: number[] = chart.timestamp ?? []\n const closes: number[] = chart.indicators?.quote?.[0]?.close ?? []\n\n const dates: string[] = []\n const prices: number[] = []\n\n for (let i = 0; i < timestamps.length; i++) {\n if (closes[i] != null) {\n dates.push(new Date((timestamps[i] ?? 0) * 1000).toISOString().split('T')[0]!)\n prices.push(closes[i] as number)\n }\n }\n\n return { dates, prices }\n}\n\nfunction _n(v: unknown): number | null {\n if (v == null) return null\n const raw = typeof v === 'object' ? (v as any).raw ?? v : v\n const n = Number(raw)\n return isNaN(n) ? null : n\n}\n"]}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core financial statement types.
|
|
3
|
+
* All monetary values should be in the same currency unit (e.g., USD thousands).
|
|
4
|
+
* Use null for unavailable/inapplicable fields.
|
|
5
|
+
*/
|
|
6
|
+
interface IncomeStatement {
|
|
7
|
+
/** Total revenue / net sales */
|
|
8
|
+
revenue: number;
|
|
9
|
+
/** Revenue minus cost of goods sold */
|
|
10
|
+
grossProfit: number;
|
|
11
|
+
/** Cost of goods sold */
|
|
12
|
+
cogs: number;
|
|
13
|
+
/** Earnings before interest and taxes */
|
|
14
|
+
ebit: number;
|
|
15
|
+
/** EBIT + Depreciation + Amortization */
|
|
16
|
+
ebitda: number;
|
|
17
|
+
/** Net income after all expenses and taxes */
|
|
18
|
+
netIncome: number;
|
|
19
|
+
/** Interest expense (positive = expense) */
|
|
20
|
+
interestExpense: number;
|
|
21
|
+
/** Income tax expense */
|
|
22
|
+
incomeTaxExpense: number;
|
|
23
|
+
/** Earnings before taxes */
|
|
24
|
+
ebt: number;
|
|
25
|
+
/** Depreciation and amortization */
|
|
26
|
+
depreciationAndAmortization: number;
|
|
27
|
+
/** Research and development expense */
|
|
28
|
+
researchAndDevelopment?: number | null;
|
|
29
|
+
/** Selling, general and administrative expense */
|
|
30
|
+
sgaExpense?: number | null;
|
|
31
|
+
/** Basic shares outstanding */
|
|
32
|
+
sharesOutstanding: number;
|
|
33
|
+
/** Diluted shares outstanding */
|
|
34
|
+
sharesOutstandingDiluted?: number | null;
|
|
35
|
+
/** Earnings per share (basic) */
|
|
36
|
+
eps?: number | null;
|
|
37
|
+
/** Earnings per share (diluted) */
|
|
38
|
+
epsDiluted?: number | null;
|
|
39
|
+
/** Fiscal period label, e.g. "2024-Q1" or "FY2023" */
|
|
40
|
+
period?: string;
|
|
41
|
+
}
|
|
42
|
+
interface BalanceSheet {
|
|
43
|
+
/** Total assets */
|
|
44
|
+
totalAssets: number;
|
|
45
|
+
/** Current assets */
|
|
46
|
+
currentAssets: number;
|
|
47
|
+
/** Cash and cash equivalents */
|
|
48
|
+
cash: number;
|
|
49
|
+
/** Short-term investments */
|
|
50
|
+
shortTermInvestments?: number | null;
|
|
51
|
+
/** Accounts receivable */
|
|
52
|
+
accountsReceivable: number;
|
|
53
|
+
/** Inventory */
|
|
54
|
+
inventory: number;
|
|
55
|
+
/** Net PP&E (property, plant, equipment) */
|
|
56
|
+
netPPE: number;
|
|
57
|
+
/** Goodwill */
|
|
58
|
+
goodwill?: number | null;
|
|
59
|
+
/** Intangible assets (excluding goodwill) */
|
|
60
|
+
intangibleAssets?: number | null;
|
|
61
|
+
/** Retained earnings */
|
|
62
|
+
retainedEarnings: number;
|
|
63
|
+
/** Total liabilities */
|
|
64
|
+
totalLiabilities: number;
|
|
65
|
+
/** Current liabilities */
|
|
66
|
+
currentLiabilities: number;
|
|
67
|
+
/** Accounts payable */
|
|
68
|
+
accountsPayable: number;
|
|
69
|
+
/** Short-term debt */
|
|
70
|
+
shortTermDebt?: number | null;
|
|
71
|
+
/** Long-term debt */
|
|
72
|
+
longTermDebt: number;
|
|
73
|
+
/** Total debt (short-term + long-term) */
|
|
74
|
+
totalDebt: number;
|
|
75
|
+
/** Total shareholders' equity */
|
|
76
|
+
totalEquity: number;
|
|
77
|
+
/** Number of shares outstanding */
|
|
78
|
+
sharesOutstanding?: number | null;
|
|
79
|
+
period?: string;
|
|
80
|
+
}
|
|
81
|
+
interface CashFlowStatement {
|
|
82
|
+
/** Cash from operating activities */
|
|
83
|
+
operatingCashFlow: number;
|
|
84
|
+
/** Capital expenditures (positive = spending, negative also common) */
|
|
85
|
+
capex: number;
|
|
86
|
+
/** Cash from investing activities */
|
|
87
|
+
investingCashFlow?: number | null;
|
|
88
|
+
/** Cash from financing activities */
|
|
89
|
+
financingCashFlow?: number | null;
|
|
90
|
+
/** Net change in cash */
|
|
91
|
+
netChangeInCash?: number | null;
|
|
92
|
+
/** Stock-based compensation */
|
|
93
|
+
stockBasedCompensation?: number | null;
|
|
94
|
+
/** Dividends paid */
|
|
95
|
+
dividendsPaid?: number | null;
|
|
96
|
+
/** Debt repayments */
|
|
97
|
+
debtRepayments?: number | null;
|
|
98
|
+
/** Debt issuance */
|
|
99
|
+
debtIssuance?: number | null;
|
|
100
|
+
/** Depreciation and amortization (from cash flow statement) */
|
|
101
|
+
depreciationAndAmortization?: number | null;
|
|
102
|
+
period?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convenience bundle of all three statements for a single period.
|
|
106
|
+
*/
|
|
107
|
+
interface FinancialStatements {
|
|
108
|
+
income: IncomeStatement;
|
|
109
|
+
balance: BalanceSheet;
|
|
110
|
+
cashFlow: CashFlowStatement;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type { BalanceSheet as B, CashFlowStatement as C, FinancialStatements as F, IncomeStatement as I };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core financial statement types.
|
|
3
|
+
* All monetary values should be in the same currency unit (e.g., USD thousands).
|
|
4
|
+
* Use null for unavailable/inapplicable fields.
|
|
5
|
+
*/
|
|
6
|
+
interface IncomeStatement {
|
|
7
|
+
/** Total revenue / net sales */
|
|
8
|
+
revenue: number;
|
|
9
|
+
/** Revenue minus cost of goods sold */
|
|
10
|
+
grossProfit: number;
|
|
11
|
+
/** Cost of goods sold */
|
|
12
|
+
cogs: number;
|
|
13
|
+
/** Earnings before interest and taxes */
|
|
14
|
+
ebit: number;
|
|
15
|
+
/** EBIT + Depreciation + Amortization */
|
|
16
|
+
ebitda: number;
|
|
17
|
+
/** Net income after all expenses and taxes */
|
|
18
|
+
netIncome: number;
|
|
19
|
+
/** Interest expense (positive = expense) */
|
|
20
|
+
interestExpense: number;
|
|
21
|
+
/** Income tax expense */
|
|
22
|
+
incomeTaxExpense: number;
|
|
23
|
+
/** Earnings before taxes */
|
|
24
|
+
ebt: number;
|
|
25
|
+
/** Depreciation and amortization */
|
|
26
|
+
depreciationAndAmortization: number;
|
|
27
|
+
/** Research and development expense */
|
|
28
|
+
researchAndDevelopment?: number | null;
|
|
29
|
+
/** Selling, general and administrative expense */
|
|
30
|
+
sgaExpense?: number | null;
|
|
31
|
+
/** Basic shares outstanding */
|
|
32
|
+
sharesOutstanding: number;
|
|
33
|
+
/** Diluted shares outstanding */
|
|
34
|
+
sharesOutstandingDiluted?: number | null;
|
|
35
|
+
/** Earnings per share (basic) */
|
|
36
|
+
eps?: number | null;
|
|
37
|
+
/** Earnings per share (diluted) */
|
|
38
|
+
epsDiluted?: number | null;
|
|
39
|
+
/** Fiscal period label, e.g. "2024-Q1" or "FY2023" */
|
|
40
|
+
period?: string;
|
|
41
|
+
}
|
|
42
|
+
interface BalanceSheet {
|
|
43
|
+
/** Total assets */
|
|
44
|
+
totalAssets: number;
|
|
45
|
+
/** Current assets */
|
|
46
|
+
currentAssets: number;
|
|
47
|
+
/** Cash and cash equivalents */
|
|
48
|
+
cash: number;
|
|
49
|
+
/** Short-term investments */
|
|
50
|
+
shortTermInvestments?: number | null;
|
|
51
|
+
/** Accounts receivable */
|
|
52
|
+
accountsReceivable: number;
|
|
53
|
+
/** Inventory */
|
|
54
|
+
inventory: number;
|
|
55
|
+
/** Net PP&E (property, plant, equipment) */
|
|
56
|
+
netPPE: number;
|
|
57
|
+
/** Goodwill */
|
|
58
|
+
goodwill?: number | null;
|
|
59
|
+
/** Intangible assets (excluding goodwill) */
|
|
60
|
+
intangibleAssets?: number | null;
|
|
61
|
+
/** Retained earnings */
|
|
62
|
+
retainedEarnings: number;
|
|
63
|
+
/** Total liabilities */
|
|
64
|
+
totalLiabilities: number;
|
|
65
|
+
/** Current liabilities */
|
|
66
|
+
currentLiabilities: number;
|
|
67
|
+
/** Accounts payable */
|
|
68
|
+
accountsPayable: number;
|
|
69
|
+
/** Short-term debt */
|
|
70
|
+
shortTermDebt?: number | null;
|
|
71
|
+
/** Long-term debt */
|
|
72
|
+
longTermDebt: number;
|
|
73
|
+
/** Total debt (short-term + long-term) */
|
|
74
|
+
totalDebt: number;
|
|
75
|
+
/** Total shareholders' equity */
|
|
76
|
+
totalEquity: number;
|
|
77
|
+
/** Number of shares outstanding */
|
|
78
|
+
sharesOutstanding?: number | null;
|
|
79
|
+
period?: string;
|
|
80
|
+
}
|
|
81
|
+
interface CashFlowStatement {
|
|
82
|
+
/** Cash from operating activities */
|
|
83
|
+
operatingCashFlow: number;
|
|
84
|
+
/** Capital expenditures (positive = spending, negative also common) */
|
|
85
|
+
capex: number;
|
|
86
|
+
/** Cash from investing activities */
|
|
87
|
+
investingCashFlow?: number | null;
|
|
88
|
+
/** Cash from financing activities */
|
|
89
|
+
financingCashFlow?: number | null;
|
|
90
|
+
/** Net change in cash */
|
|
91
|
+
netChangeInCash?: number | null;
|
|
92
|
+
/** Stock-based compensation */
|
|
93
|
+
stockBasedCompensation?: number | null;
|
|
94
|
+
/** Dividends paid */
|
|
95
|
+
dividendsPaid?: number | null;
|
|
96
|
+
/** Debt repayments */
|
|
97
|
+
debtRepayments?: number | null;
|
|
98
|
+
/** Debt issuance */
|
|
99
|
+
debtIssuance?: number | null;
|
|
100
|
+
/** Depreciation and amortization (from cash flow statement) */
|
|
101
|
+
depreciationAndAmortization?: number | null;
|
|
102
|
+
period?: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convenience bundle of all three statements for a single period.
|
|
106
|
+
*/
|
|
107
|
+
interface FinancialStatements {
|
|
108
|
+
income: IncomeStatement;
|
|
109
|
+
balance: BalanceSheet;
|
|
110
|
+
cashFlow: CashFlowStatement;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export type { BalanceSheet as B, CashFlowStatement as C, FinancialStatements as F, IncomeStatement as I };
|