docs: add API references, mapping corrections, and verification script

- Add yfinance.org and defeatbeta-api.org reference docs
- Fix defeatbeta_mapping.org: deprecated yfinance property names
  (quarterly_financials→quarterly_income_stmt, financials→income_stmt),
  longName vs longBusinessSummary conceptual mismatch, cashflow note typo
- Add Mapping Limitations section with live verification results (AAPL):
  DuckDB 1.4.3 incompatibility, format differences, coverage gaps
- Add docs/test_mapping.py as runnable mapping verification script
- Add offline.py, persistent_cache.py, download_data.py, warmup_cache.py
  for offline/cached defeatbeta usage
- Add aapl_yfinance.py exploration script and quant.py scaffold
- Add .envrc (uv layout) and update pyproject.toml + uv.lock

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-26 15:33:21 +08:00
parent b71a8e77b0
commit b5bf689e72
16 changed files with 3650 additions and 141 deletions
+186 -128
View File
@@ -7,20 +7,20 @@
# Overview
| Category | Yahoo Finance | DefeatBeta-API | Notes |
|----------|--------------|----------------|-------|
| **Data Source** | Yahoo Finance API | HuggingFace + DuckDB | No rate limits |
| **Query Engine** | Direct API | DuckDB OLAP | Sub-second queries |
| **Update Frequency** | Real-time (15min delayed) | Daily batch | DefeatBeta is historical only |
| **Historical Depth** | Full history | Full history | Comparable coverage |
| **Special Features** | Limited | Earnings transcripts, DCF, AI | DefeatBeta has unique capabilities |
| Category | Yahoo Finance | DefeatBeta-API | Notes |
|--------------------+---------------------------+-------------------------------+------------------------------------|
| **Data Source** | Yahoo Finance API | HuggingFace + DuckDB | No rate limits |
| **Query Engine** | Direct API | DuckDB OLAP | Sub-second queries |
| **Update Frequency** | Real-time (15min delayed) | Daily batch | DefeatBeta is historical only |
| **Historical Depth** | Full history | Full history | Comparable coverage |
| **Special Features** | Limited | Earnings transcripts, DCF, AI | DefeatBeta has unique capabilities |
* Price & Volume Data
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.history(period='max')~ | ~ticker.price()~ | pandas.DataFrame | OHLCV data |
| ~ticker.history(period='1d')~ | N/A | - | Real-time not available |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|----------------------------------------+-------------------------+------------------+--------------------------|
| ~ticker.history(period='max')~ | ~ticker.price()~ | pandas.DataFrame | OHLCV data |
| ~ticker.history(period='1d')~ | N/A | - | Real-time not available |
| ~ticker.history(start='...', end='...')~ | ~ticker.price()~ (filter) | pandas.DataFrame | Date filtering available |
* DefeatBeta Price Data Structure
@@ -33,14 +33,14 @@
* Financial Statements
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.quarterly_financials~ | ~ticker.quarterly_income_statement()~ | Statement object | Different format |
| ~ticker.financials~ | ~ticker.annual_income_statement()~ | Statement object | Annual version |
| ~ticker.quarterly_balance_sheet~ | ~ticker.quarterly_balance_sheet()~ | Statement object | Same structure |
| ~ticker.balance_sheet~ | ~ticker.annual_balance_sheet()~ | Statement object | Annual version |
| ~ticker.quarterly_cashflow~ | ~ticker.quarterly_cash_flow()~ | Statement object | Note: 'flow' vs 'flow' |
| ~ticker.cashflow~ | ~ticker.annual_cash_flow()~ | Statement object | Annual version |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------------------------+-------------------------------------+------------------+------------------------|
| ~ticker.quarterly_income_stmt~ | ~ticker.quarterly_income_statement()~ | Statement object | Different format |
| ~ticker.income_stmt~ | ~ticker.annual_income_statement()~ | Statement object | Annual version |
| ~ticker.quarterly_balance_sheet~ | ~ticker.quarterly_balance_sheet()~ | Statement object | Same structure |
| ~ticker.balance_sheet~ | ~ticker.annual_balance_sheet()~ | Statement object | Annual version |
| ~ticker.quarterly_cashflow~ | ~ticker.quarterly_cash_flow()~ | Statement object | 'cashflow' vs 'cash_flow' |
| ~ticker.cashflow~ | ~ticker.annual_cash_flow()~ | Statement object | Annual version |
** Statement Object Methods
#+BEGIN_SRC python
@@ -53,16 +53,16 @@ income_stmt.print_pretty_table() # Formatted output
* Valuation Metrics
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.info['trailingPE']~ | ~ticker.ttm_pe()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['forwardPE']~ | N/A | - | Not available |
| ~ticker.info['trailingEps']~ | ~ticker.ttm_eps()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['forwardEps']~ | N/A | - | Not available |
| ~ticker.info['marketCap']~ | ~ticker.market_capitalization()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['priceToBook']~ | ~ticker.pb_ratio()~ | pandas.DataFrame | Price/Book ratio |
| ~ticker.info['priceToSalesTrailing12Months']~ | ~ticker.ps_ratio()~ | pandas.DataFrame | Price/Sales ratio |
| N/A | ~ticker.peg_ratio()~ | pandas.DataFrame | PEG ratio (unique) |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|---------------------------------------------+--------------------------------+------------------+---------------------------|
| ~ticker.info['trailingPE']~ | ~ticker.ttm_pe()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['forwardPE']~ | N/A | - | Not available |
| ~ticker.info['trailingEps']~ | ~ticker.ttm_eps()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['forwardEps']~ | N/A | - | Not available |
| ~ticker.info['marketCap']~ | ~ticker.market_capitalization()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['priceToBook']~ | ~ticker.pb_ratio()~ | pandas.DataFrame | Price/Book ratio |
| ~ticker.info['priceToSalesTrailing12Months']~ | ~ticker.ps_ratio()~ | pandas.DataFrame | Price/Sales ratio |
| N/A | ~ticker.peg_ratio()~ | pandas.DataFrame | PEG ratio (unique) |
** Key Advantage: Historical Valuation Data
DefeatBeta provides **full historical time series** for:
@@ -75,13 +75,13 @@ Yahoo Finance only provides **current values** in ~.info~
* Financial Ratios
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.info['returnOnEquity']~ | ~ticker.roe()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['returnOnAssets']~ | ~ticker.roa()~ | pandas.DataFrame | **Historical** time series! |
| N/A | ~ticker.roic()~ | pandas.DataFrame | Return on Invested Capital |
| N/A | ~ticker.wacc()~ | pandas.DataFrame | Weighted Avg Cost of Capital |
| ~ticker.info['beta']~ | ~ticker.beta()~ | pandas.DataFrame | 5Y monthly beta |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|-------------------------------+----------------+------------------+------------------------------|
| ~ticker.info['returnOnEquity']~ | ~ticker.roe()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['returnOnAssets']~ | ~ticker.roa()~ | pandas.DataFrame | **Historical** time series! |
| N/A | ~ticker.roic()~ | pandas.DataFrame | Return on Invested Capital |
| N/A | ~ticker.wacc()~ | pandas.DataFrame | Weighted Avg Cost of Capital |
| ~ticker.info['beta']~ | ~ticker.beta()~ | pandas.DataFrame | 5Y monthly beta |
** WACC Components Available in DefeatBeta
#+BEGIN_SRC python
@@ -93,66 +93,67 @@ wacc = ticker.wacc()
* Growth Metrics
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.info['revenueGrowth']~ | ~ticker.quarterly_revenue_yoy_growth()~ | pandas.DataFrame | YoY growth |
| ~ticker.info['earningsGrowth']~ | ~ticker.quarterly_eps_yoy_growth()~ | pandas.DataFrame | EPS YoY growth |
| N/A | ~ticker.quarterly_net_income_yoy_growth()~ | pandas.DataFrame | Net income growth |
| N/A | ~ticker.quarterly_operating_income_yoy_growth()~ | pandas.DataFrame | Operating income growth |
| N/A | ~ticker.quarterly_ebitda_yoy_growth()~ | pandas.DataFrame | EBITDA growth |
| N/A | ~ticker.quarterly_fcf_yoy_growth()~ | pandas.DataFrame | Free cash flow growth |
| N/A | ~ticker.annual_revenue_yoy_growth()~ | pandas.DataFrame | Annual revenue growth |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|-------------------------------+------------------------------------------------+------------------+-------------------------|
| ~ticker.info['revenueGrowth']~ | ~ticker.quarterly_revenue_yoy_growth()~ | pandas.DataFrame | YoY growth |
| ~ticker.info['earningsGrowth']~ | ~ticker.quarterly_eps_yoy_growth()~ | pandas.DataFrame | EPS YoY growth |
| N/A | ~ticker.quarterly_net_income_yoy_growth()~ | pandas.DataFrame | Net income growth |
| N/A | ~ticker.quarterly_operating_income_yoy_growth()~ | pandas.DataFrame | Operating income growth |
| N/A | ~ticker.quarterly_ebitda_yoy_growth()~ | pandas.DataFrame | EBITDA growth |
| N/A | ~ticker.quarterly_fcf_yoy_growth()~ | pandas.DataFrame | Free cash flow growth |
| N/A | ~ticker.annual_revenue_yoy_growth()~ | pandas.DataFrame | Annual revenue growth |
* Margin Metrics
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.info['profitMargins']~ | ~ticker.quarterly_net_margin()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['grossMargins']~ | ~ticker.quarterly_gross_margin()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['operatingMargins']~ | ~ticker.quarterly_operating_margin()~ | pandas.DataFrame | **Historical** time series! |
| N/A | ~ticker.quarterly_ebitda_margin()~ | pandas.DataFrame | EBITDA margin |
| N/A | ~ticker.quarterly_fcf_margin()~ | pandas.DataFrame | Free cash flow margin |
| N/A | ~ticker.industry_quarterly_gross_margin()~ | pandas.DataFrame | Industry comparison |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|---------------------------------+------------------------------------------+------------------+---------------------------|
| ~ticker.info['profitMargins']~ | ~ticker.quarterly_net_margin()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['grossMargins']~ | ~ticker.quarterly_gross_margin()~ | pandas.DataFrame | **Historical** time series! |
| ~ticker.info['operatingMargins']~ | ~ticker.quarterly_operating_margin()~ | pandas.DataFrame | **Historical** time series! |
| N/A | ~ticker.quarterly_ebitda_margin()~ | pandas.DataFrame | EBITDA margin |
| N/A | ~ticker.quarterly_fcf_margin()~ | pandas.DataFrame | Free cash flow margin |
| N/A | ~ticker.industry_quarterly_gross_margin()~ | pandas.DataFrame | Industry comparison |
* Dividends & Stock Splits
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.dividends~ | ~ticker.dividends()~ | pandas.DataFrame | Dividend history |
| ~ticker.splits~ | ~ticker.splits()~ | pandas.DataFrame | Stock split history |
| ~ticker.info['dividendYield']~ | N/A | - | Not in separate field |
| ~ticker.info['trailingAnnualDividendYield']~ | N/A | - | Not available |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------------------------------------+--------------------+------------------+-----------------------|
| ~ticker.dividends~ | ~ticker.dividends()~ | pandas.DataFrame | Dividend history |
| ~ticker.splits~ | ~ticker.splits()~ | pandas.DataFrame | Stock split history |
| ~ticker.info['dividendYield']~ | N/A | - | Not in separate field |
| ~ticker.info['trailingAnnualDividendYield']~ | N/A | - | Not available |
* Company Info & Metadata
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|--------------|----------------|-------------|-------|
| ~ticker.info~ | ~ticker.info()~ | pandas.DataFrame | One row, many columns |
| ~ticker.info['longName']~ | ~ticker.info()['long_business_summary']~ | string | Business summary |
| ~ticker.info['sector']~ | ~ticker.info()['sector']~ | string | Sector classification |
| ~ticker.info['industry']~ | ~ticker.info()['industry']~ | string | Industry classification |
| ~ticker.info['website']~ | ~ticker.info()['web_site']~ | string | Company website |
| ~ticker.info['fullTimeEmployees']~ | ~ticker.info()['full_time_employees']~ | int | Employee count |
| N/A | ~ticker.officers()~ | pandas.DataFrame | Company officers |
| N/A | ~ticker.calendar()~ | pandas.DataFrame | Earnings calendar |
| Yahoo Finance | DefeatBeta-API | Return Type | Notes |
|----------------------------------+----------------------------------------+------------------+-------------------------|
| ~ticker.info~ | ~ticker.info()~ | pandas.DataFrame | One row, many columns |
| ~ticker.info['longName']~ | N/A (check name/short_name column) | string | Company trading name |
| ~ticker.info['longBusinessSummary']~ | ~ticker.info()['long_business_summary']~ | string | Business description |
| ~ticker.info['sector']~ | ~ticker.info()['sector']~ | string | Sector classification |
| ~ticker.info['industry']~ | ~ticker.info()['industry']~ | string | Industry classification |
| ~ticker.info['website']~ | ~ticker.info()['web_site']~ | string | Company website |
| ~ticker.info['fullTimeEmployees']~ | ~ticker.info()['full_time_employees']~ | int | Employee count |
| N/A | ~ticker.officers()~ | pandas.DataFrame | Company officers |
| N/A | ~ticker.calendar()~ | pandas.DataFrame | Earnings calendar |
* Unique DefeatBeta Features (Not in Yahoo Finance)
| Feature | Method | Description |
|---------|--------|-------------|
| **Earnings Transcripts** | ~ticker.earning_call_transcripts()~ | Full earnings call transcripts |
| | ~transcripts.get_transcripts_list()~ | List all available transcripts |
| | ~transcripts.get_transcript(year, quarter)~ | Get specific quarter's transcript |
| | ~transcripts.summarize_key_financial_data_with_ai()~ | AI-powered summary |
| **Revenue Breakdown** | ~ticker.revenue_by_segment()~ | Revenue by product segment |
| | ~ticker.revenue_by_product()~ | Detailed product breakdown |
| | ~ticker.revenue_by_geography()~ | Revenue by geographic region |
| **Automated DCF** | ~ticker.dcf()~ | Generates Excel DCF valuation |
| **AI Analysis** | ~transcripts.analyze_financial_metrics_change...~ | LLM analysis of quarter changes |
| | ~transcripts.analyze_financial_metrics_forecast...~ | LLM forecast analysis |
| **Industry Metrics** | ~ticker.industry_ttm_pe()~ | Industry P/E comparison |
| | ~ticker.industry_roe()~ | Industry ROE comparison |
| | ~ticker.industry_quarterly_gross_margin()~ | Industry margin comparison |
| Feature | Method | Description |
|------------------------+----------------------------------------------------+-----------------------------------|
| **Earnings Transcripts** | ~ticker.earning_call_transcripts()~ | Full earnings call transcripts |
| | ~transcripts.get_transcripts_list()~ | List all available transcripts |
| | ~transcripts.get_transcript(year, quarter)~ | Get specific quarter's transcript |
| | ~transcripts.summarize_key_financial_data_with_ai()~ | AI-powered summary |
| **Revenue Breakdown** | ~ticker.revenue_by_segment()~ | Revenue by product segment |
| | ~ticker.revenue_by_product()~ | Detailed product breakdown |
| | ~ticker.revenue_by_geography()~ | Revenue by geographic region |
| **Automated DCF** | ~ticker.dcf()~ | Generates Excel DCF valuation |
| **AI Analysis** | ~transcripts.analyze_financial_metrics_change...~ | LLM analysis of quarter changes |
| | ~transcripts.analyze_financial_metrics_forecast...~ | LLM forecast analysis |
| **Industry Metrics** | ~ticker.industry_ttm_pe()~ | Industry P/E comparison |
| | ~ticker.industry_roe()~ | Industry ROE comparison |
| | ~ticker.industry_quarterly_gross_margin()~ | Industry margin comparison |
* Example: yfinance → DefeatBeta Migration
@@ -209,26 +210,26 @@ current_roe = ticker.roe().iloc[-1]['roe']
* Quick Reference: Common Operations
| Operation | Yahoo Finance | DefeatBeta-API |
|-----------|--------------|----------------|
| Get current price | ~ticker.info['currentPrice']~ | ~ticker.price().iloc[-1]['close']~ |
| Get current P/E | ~ticker.info['trailingPE']~ | ~ticker.ttm_pe().iloc[-1]['ttm_pe']~ |
| Get current EPS | ~ticker.info['trailingEps']~ | ~ticker.ttm_eps().iloc[-1]['tailing_eps']~ |
| Get market cap | ~ticker.info['marketCap']~ | ~ticker.market_capitalization().iloc[-1]['market_capitalization']~ |
| Get ROE | ~ticker.info['returnOnEquity']~ | ~ticker.roe().iloc[-1]['roe']~ |
| Get revenue (TTM) | ~ticker.info['totalRevenue']~ | ~ticker.quarterly_income_statement().df().iloc[0]['TTM']~ |
| Get 5Y beta | ~ticker.info['beta']~ | ~ticker.beta().iloc[-1]['beta']~ |
| Operation | Yahoo Finance | DefeatBeta-API |
|-------------------+-------------------------------+------------------------------------------------------------------|
| Get current price | ~ticker.info['currentPrice']~ | ~ticker.price().iloc[-1]['close']~ |
| Get current P/E | ~ticker.info['trailingPE']~ | ~ticker.ttm_pe().iloc[-1]['ttm_pe']~ |
| Get current EPS | ~ticker.info['trailingEps']~ | ~ticker.ttm_eps().iloc[-1]['tailing_eps']~ |
| Get market cap | ~ticker.info['marketCap']~ | ~ticker.market_capitalization().iloc[-1]['market_capitalization']~ |
| Get ROE | ~ticker.info['returnOnEquity']~ | ~ticker.roe().iloc[-1]['roe']~ |
| Get revenue (TTM) | ~ticker.info['totalRevenue']~ | ~ticker.quarterly_income_statement().df().iloc[0]['TTM']~ |
| Get 5Y beta | ~ticker.info['beta']~ | ~ticker.beta().iloc[-1]['beta']~ |
* Data Type Differences
| Aspect | Yahoo Finance | DefeatBeta-API |
|--------|--------------|----------------|
| Dates in DataFrame | DatetimeIndex | 'report_date' column |
| Column naming | Title case (Open, Close) | Snake case (open, close) |
| Dividends/Splits | Separate columns in history | Separate DataFrames |
| Quarterly data | Transposed (dates as columns) | Wide format (TTM + quarters as columns) |
| Missing data | NaN | NaN |
| Numeric types | float | Decimal (convert with ~float()~) |
| Aspect | Yahoo Finance | DefeatBeta-API |
|--------------------+-------------------------------+-----------------------------------------|
| Dates in DataFrame | DatetimeIndex | 'report_date' column |
| Column naming | Title case (Open, Close) | Snake case (open, close) |
| Dividends/Splits | Separate columns in history | Separate DataFrames |
| Quarterly data | Transposed (dates as columns) | Wide format (TTM + quarters as columns) |
| Missing data | NaN | NaN |
| Numeric types | float | Decimal (convert with ~float()~) |
* Converting Decimal to Float
#+BEGIN_SRC python
@@ -244,37 +245,94 @@ market_cap_billions = float(market_cap.iloc[-1]['market_capitalization']) / 1e9
* When to Use Each
| Use Case | Recommendation | Reason |
|----------|---------------|--------|
| Backtesting trading strategies | **DefeatBeta** | No rate limits, consistent historical data |
| DCF Valuation modeling | **DefeatBeta** | Automated Excel output |
| Revenue segment analysis | **DefeatBeta** | Unique revenue breakdown |
| Earnings call research | **DefeatBeta** | Full transcripts available |
| Real-time price alerts | **Yahoo Finance** | 15min delayed but real-time |
| Analyst recommendations | **Yahoo Finance** | Price targets, ratings |
| Institutional ownership | **Yahoo Finance** | Major holders data |
| Options/derivatives data | **Yahoo Finance** | Not available in DefeatBeta |
| Quick stock lookup | **Either** | Both work well |
| Multi-year historical analysis | **DefeatBeta** | Faster queries, no rate limits |
| Use Case | Recommendation | Reason |
|--------------------------------+-----------------+--------------------------------------------|
| Backtesting trading strategies | **DefeatBeta** | No rate limits, consistent historical data |
| DCF Valuation modeling | **DefeatBeta** | Automated Excel output |
| Revenue segment analysis | **DefeatBeta** | Unique revenue breakdown |
| Earnings call research | **DefeatBeta** | Full transcripts available |
| Real-time price alerts | **Yahoo Finance** | 15min delayed but real-time |
| Analyst recommendations | **Yahoo Finance** | Price targets, ratings |
| Institutional ownership | **Yahoo Finance** | Major holders data |
| Options/derivatives data | **Yahoo Finance** | Not available in DefeatBeta |
| Quick stock lookup | **Either** | Both work well |
| Multi-year historical analysis | **DefeatBeta** | Faster queries, no rate limits |
* Environment Setup
| Task | Command |
|------|---------|
| Install DefeatBeta | ~uv add defeatbeta-api~ |
| Install yfinance | ~uv add yfinance~ |
| Run notebook | ~uv run jupyter notebook~ |
| Check version | ~ticker.price()~ shows data update date |
| Task | Command |
|--------------------+---------------------------------------|
| Install DefeatBeta | ~uv add defeatbeta-api~ |
| Install yfinance | ~uv add yfinance~ |
| Run notebook | ~uv run jupyter notebook~ |
| Check version | ~ticker.price()~ shows data update date |
* Mapping Limitations & Verification Notes
/Verified 2026-04-26 via test_mapping.py on AAPL. defeatbeta-api 0.0.45, yfinance 1.3.0, DuckDB 1.4.3./
** What was confirmed correct (live data matched)
- ~dividends()~: both APIs return $0.26 for Nov-2025 and Feb-2026 payments — values match exactly
- ~splits()~: both return the same ratios (7:1 in 2014, 4:1 in 2020)
** Incorrect property names for yfinance (deprecated in v1.3)
| Used in mapping | Correct name in yfinance 1.3+ |
|----------------------------+-------------------------------|
| ~ticker.quarterly_financials~ | ~ticker.quarterly_income_stmt~ |
| ~ticker.financials~ | ~ticker.income_stmt~ |
The old names were removed. The mapping should use the new names.
** Conceptual mismatch: longName vs long_business_summary (Company Info)
The mapping equates ~ticker.info['longName']~ with ~ticker.info()['long_business_summary']~,
labelling it "Business summary". This is wrong:
- ~longName~ = company trading name, e.g. "Apple Inc."
- ~long_business_summary~ = multi-sentence business description paragraph
- The yfinance equivalent of the description is ~ticker.info['longBusinessSummary']~
** Typo in Financial Statements note (cashflow row)
The "Notes" column reads ~Note: 'flow' vs 'flow'~. Should read: ~'cashflow' vs 'cash_flow'~
** Data format differences found in verified pairs
| Field | yfinance | defeatbeta |
|---------------+--------------------------------------+-------------------------------|
| dividends | Series, DatetimeIndex, float amount | DataFrame, report_date col |
| split_factor | float (e.g. ~7.0~) | string ratio (e.g. ~"7:1"~) |
** Historical coverage gap
- Dividends: yfinance returns 90 records, defeatbeta returns 61 (truncated history)
- Splits: yfinance returns 5 events, defeatbeta returns 4 (one historical split missing)
** DuckDB compatibility issue (defeatbeta-api 0.0.45 + DuckDB 1.4.3)
All Parquet-backed queries except ~dividends()~ and ~splits()~ failed during verification
with either ~"don't know what type:"~ or ~"TProtocolException: Invalid data"~. Affected:
~price()~, all financial statements, all valuation/ratio/margin/growth metrics, ~info()~, ~beta()~.
This is an incompatibility between DuckDB 1.4.3 and the httpfs extension / remote Parquet
format used by defeatbeta-api. Downgrading DuckDB or waiting for a defeatbeta-api update
may resolve it. The logical mapping is still valid — the API shape is correct, only the
DuckDB query layer is broken.
** Data freshness
DefeatBeta dataset last updated 2026-04-17, 9 days behind current date. yfinance has
15-minute delayed real-time data. This gap will always exist for defeatbeta.
* Common Issues & Solutions
| Issue | Solution |
|-------|----------|
| ~TypeError: unsupported operand type(s) for /: 'Decimal' and 'float'~ | Wrap values in ~float()~ |
| ~Rate limit exceeded~ | Switch to DefeatBeta |
| ~Real-time data needed~ | Use Yahoo Finance |
| ~Missing revenue breakdown~ | Use DefeatBeta ~revenue_by_segment()~ |
| ~Slow queries~ | Use DefeatBeta (DuckDB engine) |
| Issue | Solution |
|---------------------------------------------------------------------+-------------------------------------|
| ~TypeError: unsupported operand type(s) for /: 'Decimal' and 'float'~ | Wrap values in ~float()~ |
| ~Rate limit exceeded~ | Switch to DefeatBeta |
| ~Real-time data needed~ | Use Yahoo Finance |
| ~Missing revenue breakdown~ | Use DefeatBeta ~revenue_by_segment()~ |
| ~Slow queries~ | Use DefeatBeta (DuckDB engine) |
* Additional Resources
@@ -285,7 +343,7 @@ market_cap_billions = float(market_cap.iloc[-1]['market_capitalization']) / 1e9
* Footer
#+BEGIN_COMMENT
Last updated: 2026-04-25
Last updated: 2026-04-26 (verified via test_mapping.py on AAPL)
Author: Documentation
Version: 1.0
#+END_COMMENT
#+END_COMMENT