4e5af95272
- Add defeatbeta-api as primary financial data source (replaces yfinance for analysis) - Add comprehensive Jupyter notebook tutorial (defeatbeta_tutorial.ipynb) - Add API comparison script (compare_apis.py) - Add data exploration script (explore_data.py) - Add basic test script (test_defeatbeta.py) - Add notebook runner script (run_notebook.sh) - Add org-mode mapping documentation (docs/defeatbeta_mapping.org) - Update pyproject.toml with defeatbeta-api dependency - Add defeatbeta-api as git submodule for reference DefeatBeta Advantages: - No rate limits (HuggingFace hosted) - Historical financial ratios (ROE, ROIC, WACC time series) - Earnings call transcripts access - Revenue segmentation by product/geography - Automated DCF valuation with Excel output - DuckDB-powered fast queries Note: .envrc, .jupyter_checkpoints/, __marimo__/, AAPL.xlsx, tearsheet.html and other generated files intentionally excluded
203 lines
6.7 KiB
Python
203 lines
6.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script for defeatbeta-api demonstrating practical use cases
|
|
"""
|
|
|
|
import pandas as pd
|
|
from defeatbeta_api.data.ticker import Ticker
|
|
|
|
def analyze_stock(ticker_symbol):
|
|
"""Analyze a stock using defeatbeta-api"""
|
|
print(f"\n{'='*60}")
|
|
print(f"ANALYZING {ticker_symbol}")
|
|
print(f"{'='*60}")
|
|
|
|
# Create ticker instance
|
|
ticker = Ticker(ticker_symbol)
|
|
|
|
# 1. Get basic price and valuation
|
|
print("\n1. PRICE AND VALUATION:")
|
|
price_data = ticker.price()
|
|
latest_price = price_data.iloc[-1]
|
|
print(f" Latest price: ${latest_price['close']:.2f}")
|
|
print(f" Date: {latest_price['report_date']}")
|
|
print(f" Volume: {latest_price['volume']:,}")
|
|
|
|
# 2. Get TTM metrics
|
|
ttm_eps = ticker.ttm_eps()
|
|
if not ttm_eps.empty:
|
|
latest_eps = ttm_eps.iloc[-1]['tailing_eps']
|
|
print(f"\n2. TTM METRICS:")
|
|
print(f" TTM EPS: ${latest_eps:.2f}")
|
|
|
|
ttm_pe = ticker.ttm_pe()
|
|
if not ttm_pe.empty:
|
|
latest_pe = ttm_pe.iloc[-1]['ttm_pe']
|
|
print(f" TTM P/E: {latest_pe:.2f}")
|
|
|
|
# 3. Get market cap
|
|
market_cap = ticker.market_capitalization()
|
|
if not market_cap.empty:
|
|
latest_mcap = market_cap.iloc[-1]['market_capitalization']
|
|
print(f" Market Cap: ${latest_mcap:,.2f}")
|
|
|
|
# 4. Get financial ratios
|
|
print(f"\n3. FINANCIAL RATIOS:")
|
|
|
|
roe = ticker.roe()
|
|
if not roe.empty:
|
|
latest_roe = roe.iloc[-1]['roe']
|
|
print(f" ROE: {latest_roe:.2%}")
|
|
|
|
roic = ticker.roic()
|
|
if not roic.empty:
|
|
latest_roic = roic.iloc[-1]['roic']
|
|
print(f" ROIC: {latest_roic:.2%}")
|
|
|
|
wacc = ticker.wacc()
|
|
if not wacc.empty:
|
|
latest_wacc = wacc.iloc[-1]['wacc']
|
|
print(f" WACC: {latest_wacc:.2%}")
|
|
|
|
# 5. Get beta
|
|
beta_data = ticker.beta()
|
|
if not beta_data.empty:
|
|
latest_beta = beta_data.iloc[-1]['beta']
|
|
print(f" Beta (5Y): {latest_beta:.2f}")
|
|
|
|
# 6. Get growth metrics
|
|
print(f"\n4. GROWTH METRICS:")
|
|
|
|
revenue_growth = ticker.quarterly_revenue_yoy_growth()
|
|
if not revenue_growth.empty:
|
|
latest_rev_growth = revenue_growth.iloc[-1]['yoy_growth']
|
|
print(f" Quarterly Revenue YoY Growth: {latest_rev_growth:.2%}")
|
|
|
|
eps_growth = ticker.quarterly_eps_yoy_growth()
|
|
if not eps_growth.empty:
|
|
latest_eps_growth = eps_growth.iloc[-1]['yoy_growth']
|
|
print(f" Quarterly EPS YoY Growth: {latest_eps_growth:.2%}")
|
|
|
|
# 7. Get margin metrics
|
|
print(f"\n5. MARGIN METRICS:")
|
|
|
|
gross_margin = ticker.quarterly_gross_margin()
|
|
if not gross_margin.empty:
|
|
latest_gross_margin = gross_margin.iloc[-1]['gross_margin']
|
|
print(f" Gross Margin: {latest_gross_margin:.2%}")
|
|
|
|
net_margin = ticker.quarterly_net_margin()
|
|
if not net_margin.empty:
|
|
latest_net_margin = net_margin.iloc[-1]['net_margin']
|
|
print(f" Net Margin: {latest_net_margin:.2%}")
|
|
|
|
# 8. Get income statement summary
|
|
print(f"\n6. INCOME STATEMENT SUMMARY (Latest Quarter):")
|
|
income_stmt = ticker.quarterly_income_statement()
|
|
try:
|
|
income_df = income_stmt.df() # df is a method, not a property
|
|
# Get key metrics
|
|
key_metrics = ['Total Revenue', 'Gross Profit', 'Operating Income',
|
|
'Net Income Common Stockholders', 'Diluted EPS']
|
|
|
|
for metric in key_metrics:
|
|
if metric in income_df['Breakdown'].values:
|
|
row = income_df[income_df['Breakdown'] == metric]
|
|
if not row.empty:
|
|
latest_q = row.iloc[0]['TTM'] # TTM column has latest
|
|
print(f" {metric}: ${latest_q/1e6:,.2f}M" if 'Revenue' in metric or 'Profit' in metric or 'Income' in metric else f" {metric}: ${latest_q:.2f}")
|
|
except Exception as e:
|
|
print(f" Could not retrieve income statement details: {type(e).__name__}")
|
|
|
|
# 9. Get revenue breakdown
|
|
print(f"\n7. REVENUE BREAKDOWN (Latest):")
|
|
revenue_segment = ticker.revenue_by_segment()
|
|
if not revenue_segment.empty:
|
|
latest_rev = revenue_segment.iloc[-1]
|
|
print(f" Total Revenue: ${latest_rev.iloc[2:].sum():,.0f}")
|
|
for col in revenue_segment.columns[2:]: # Skip symbol and report_date
|
|
if col in latest_rev:
|
|
value = latest_rev[col]
|
|
if pd.notna(value):
|
|
print(f" {col}: ${value:,.0f}")
|
|
|
|
return ticker
|
|
|
|
def compare_stocks(tickers):
|
|
"""Compare multiple stocks"""
|
|
print(f"\n{'='*60}")
|
|
print(f"COMPARING STOCKS: {', '.join(tickers)}")
|
|
print(f"{'='*60}")
|
|
|
|
comparison_data = []
|
|
|
|
for symbol in tickers:
|
|
ticker = Ticker(symbol)
|
|
|
|
# Get key metrics
|
|
metrics = {'Symbol': symbol}
|
|
|
|
# Price
|
|
price_data = ticker.price()
|
|
if not price_data.empty:
|
|
metrics['Price'] = price_data.iloc[-1]['close']
|
|
|
|
# TTM P/E
|
|
ttm_pe = ticker.ttm_pe()
|
|
if not ttm_pe.empty:
|
|
metrics['P/E'] = ttm_pe.iloc[-1]['ttm_pe']
|
|
|
|
# Market Cap
|
|
market_cap = ticker.market_capitalization()
|
|
if not market_cap.empty:
|
|
metrics['Market Cap'] = market_cap.iloc[-1]['market_capitalization']
|
|
|
|
# ROE
|
|
roe = ticker.roe()
|
|
if not roe.empty:
|
|
metrics['ROE'] = roe.iloc[-1]['roe']
|
|
|
|
# Revenue Growth
|
|
rev_growth = ticker.quarterly_revenue_yoy_growth()
|
|
if not rev_growth.empty:
|
|
metrics['Rev Growth'] = rev_growth.iloc[-1]['yoy_growth']
|
|
|
|
comparison_data.append(metrics)
|
|
|
|
# Create comparison table
|
|
df = pd.DataFrame(comparison_data)
|
|
df.set_index('Symbol', inplace=True)
|
|
|
|
# Format the table
|
|
print(f"\n{df.to_string(float_format=lambda x: f'{x:,.2f}' if isinstance(x, (int, float)) else str(x))}")
|
|
|
|
def main():
|
|
"""Main function"""
|
|
print("DEFEATBETA-API DEMONSTRATION")
|
|
print("="*60)
|
|
|
|
# Analyze individual stocks
|
|
stocks = ['NVDA', 'TSLA', 'AAPL']
|
|
|
|
for stock in stocks[:2]: # Just analyze first 2 to keep output manageable
|
|
analyze_stock(stock)
|
|
|
|
# Compare all stocks
|
|
compare_stocks(stocks)
|
|
|
|
print(f"\n{'='*60}")
|
|
print("API FEATURES DEMONSTRATED:")
|
|
print("1. Price and volume data")
|
|
print("2. TTM EPS and P/E ratios")
|
|
print("3. Market capitalization")
|
|
print("4. Financial ratios (ROE, ROIC, WACC)")
|
|
print("5. Beta calculation")
|
|
print("6. Growth metrics (Revenue, EPS YoY)")
|
|
print("7. Margin analysis")
|
|
print("8. Income statement summary")
|
|
print("9. Revenue segmentation")
|
|
print("10. Multi-stock comparison")
|
|
print(f"{'='*60}")
|
|
|
|
if __name__ == "__main__":
|
|
main() |