Files
learn-trading/docs/defeatbeta_mapping.org
T
tomatocream b5bf689e72 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>
2026-04-26 15:33:21 +08:00

21 KiB

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
ticker.history(start='...', end='...') ticker.price() (filter) pandas.DataFrame Date filtering available

DefeatBeta Price Data Structure

# Columns: ['symbol', 'report_date', 'open', 'close', 'high', 'low', 'volume']
# Example:
     symbol report_date    open   close    high     low     volume
0    AAPL  2026-04-17  266.96  270.23  272.30  266.72  61314800

Financial Statements

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

# DefeatBeta Statement objects have these methods:
income_stmt = ticker.quarterly_income_statement()
income_stmt.df()              # Returns pandas.DataFrame
income_stmt.data()           # Alternative access
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)

Key Advantage: Historical Valuation Data

DefeatBeta provides full historical time series for:

  • TTM P/E ratios (all daily closes)
  • TTM EPS history
  • Market cap history
  • Price/Book, Price/Sales ratios

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

WACC Components Available in DefeatBeta

# Full breakdown of WACC calculation:
wacc = ticker.wacc()
# Columns: market_capitalization, beta_5y, sp500_10y_cagr, treasure_10y_yield,
#          weight_of_debt, weight_of_equity, cost_of_debt, cost_of_equity, 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

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

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

Company Info & Metadata

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

Example: yfinance → DefeatBeta Migration

Yahoo Finance Style

import yfinance as yf

ticker = yf.Ticker('AAPL')

# Current valuation
pe = ticker.info['trailingPE']
eps = ticker.info['trailingEps']
market_cap = ticker.info['marketCap']

# Financial statements
quarterly_financials = ticker.quarterly_financials
quarterly_balance = ticker.quarterly_balance_sheet

# Growth
revenue_growth = ticker.info['revenueGrowth']

DefeatBeta Equivalent

from defeatbeta_api.data.ticker import Ticker

ticker = Ticker('AAPL')

# Historical valuation time series
ttm_pe = ticker.ttm_pe()         # Full daily P/E history
ttm_eps = ticker.ttm_eps()       # Full EPS history
market_cap = ticker.market_capitalization()  # Daily market cap

# Financial statements
quarterly_income = ticker.quarterly_income_statement()
quarterly_balance = ticker.quarterly_balance_sheet()

# Convert to DataFrame
income_df = quarterly_income.df()

# Growth metrics (time series!)
revenue_growth = ticker.quarterly_revenue_yoy_growth()
eps_growth = ticker.quarterly_eps_yoy_growth()

Getting Current Values from DefeatBeta

# DefeatBeta provides time series, but getting current value is easy:
current_pe = ticker.ttm_pe().iloc[-1]['ttm_pe']
current_eps = ticker.ttm_eps().iloc[-1]['tailing_eps']
current_mcap = ticker.market_capitalization().iloc[-1]['market_capitalization']
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']

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())

Converting Decimal to Float

# DefeatBeta returns Decimal types for financial data
# Always convert before arithmetic operations

value = ticker.ttm_eps().iloc[-1]['tailing_eps']
value_float = float(value)  # Convert Decimal → float

# Use in calculations
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

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

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)

Footer

Last updated: 2026-04-26 (verified via test_mapping.py on AAPL) Author: Documentation Version: 1.0