mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-11-04 00:22:43 +02:00
fix(yahoo): print each fundamentals money figure with the currency it is in (#1456)
- price levels carry the quote currency (GBp for London), market cap and per-share figures its main unit (GBP), and income figures the reporting currency (TWD for TSMC's ADR)
This commit is contained in:
@@ -37,3 +37,43 @@ def test_an_absent_percent_field_is_left_out():
|
||||
out = _fundamentals({"longName": "JPMorgan Chase & Co.", "profitMargins": 0.35})
|
||||
|
||||
assert "Dividend Yield" not in out and "Debt to Equity" not in out
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_each_money_figure_carries_the_currency_it_is_in():
|
||||
"""Yahoo quotes London in pence but states EPS and market cap in pounds, and
|
||||
the income figures in the reporting currency (#1456)."""
|
||||
out = _fundamentals({"longName": "Shell plc", "currency": "GBp", "financialCurrency": "USD",
|
||||
"marketCap": 203440193536, "trailingEps": 3.42, "bookValue": 29.1,
|
||||
"fiftyTwoWeekHigh": 3800.0, "fiftyDayAverage": 3500.5,
|
||||
"totalRevenue": 296600993792, "netIncomeToCommon": 25970999296})
|
||||
|
||||
assert "Market Cap: 203440193536 GBP" in out
|
||||
assert "EPS (TTM): 3.42 GBP" in out and "Book Value: 29.1 GBP" in out
|
||||
assert "52 Week High: 3800.0 GBp" in out and "50 Day Average: 3500.5 GBp" in out
|
||||
assert "Revenue (TTM): 296600993792 USD" in out and "Net Income: 25970999296 USD" in out
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_an_adr_quotes_in_dollars_and_reports_in_its_home_currency():
|
||||
out = _fundamentals({"longName": "TSMC", "currency": "USD", "financialCurrency": "TWD",
|
||||
"marketCap": 2365000000000, "trailingEps": 13.21, "totalRevenue": 4440492343296})
|
||||
|
||||
assert "Market Cap: 2365000000000 USD" in out and "EPS (TTM): 13.21 USD" in out
|
||||
assert "Revenue (TTM): 4440492343296 TWD" in out
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_a_figure_with_no_stated_currency_is_printed_bare():
|
||||
out = _fundamentals({"longName": "X", "marketCap": 1000, "totalRevenue": 50})
|
||||
|
||||
assert "Market Cap: 1000\n" in out + "\n" and "Revenue (TTM): 50" in out and "None" not in out
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
def test_income_figures_without_a_stated_reporting_currency_are_printed_bare():
|
||||
"""The quote currency is not evidence of the reporting currency (an ADR quotes
|
||||
in USD and reports in TWD), so an unknown one is not guessed."""
|
||||
out = _fundamentals({"longName": "X", "currency": "USD", "marketCap": 1000, "totalRevenue": 50})
|
||||
|
||||
assert "Market Cap: 1000 USD" in out and "Revenue (TTM): 50\n" in out + "\n"
|
||||
|
||||
+30
-13
@@ -16,6 +16,9 @@ from tradingagents.dataflows.vendors.yahoo.common import (
|
||||
yf_retry,
|
||||
)
|
||||
|
||||
# Quote currencies Yahoo gives in a minor unit, and the main unit of each.
|
||||
_MAIN_UNIT = {"GBp": "GBP", "GBX": "GBP", "ZAc": "ZAR", "ILA": "ILS"}
|
||||
|
||||
|
||||
def get_fundamentals(
|
||||
ticker: Annotated[str, "ticker symbol of the company"],
|
||||
@@ -43,27 +46,41 @@ def get_fundamentals(
|
||||
# 78.4 is 78.4%, a ratio of 0.78) but the margins and returns as fractions,
|
||||
# so each carries its unit.
|
||||
dividend_yield, debt_to_equity = info.get("dividendYield"), info.get("debtToEquity")
|
||||
# Money figures come in three currencies (#1456): price levels in the quote
|
||||
# currency, which can be a minor unit (London in pence, GBp); market cap and
|
||||
# per-share figures in that currency's main unit (GBP), as Yahoo's own P/E
|
||||
# and P/B are computed against them; income figures in the currency the
|
||||
# company reports in (an ADR quotes in USD, reports in TWD), or bare when
|
||||
# Yahoo does not say which.
|
||||
quote = info.get("currency")
|
||||
main = _MAIN_UNIT.get(quote, quote)
|
||||
reported = info.get("financialCurrency")
|
||||
|
||||
def money(key, currency):
|
||||
value = info.get(key)
|
||||
return None if value is None else f"{value} {currency}" if currency else value
|
||||
|
||||
fields = [
|
||||
("Name", info.get("longName")),
|
||||
("Sector", info.get("sector")),
|
||||
("Industry", info.get("industry")),
|
||||
("Market Cap", info.get("marketCap")),
|
||||
("Market Cap", money("marketCap", main)),
|
||||
("PE Ratio (TTM)", info.get("trailingPE")),
|
||||
("Forward PE", info.get("forwardPE")),
|
||||
("PEG Ratio", info.get("pegRatio")),
|
||||
("Price to Book", info.get("priceToBook")),
|
||||
("EPS (TTM)", info.get("trailingEps")),
|
||||
("Forward EPS", info.get("forwardEps")),
|
||||
("EPS (TTM)", money("trailingEps", main)),
|
||||
("Forward EPS", money("forwardEps", main)),
|
||||
("Dividend Yield", None if dividend_yield is None else f"{dividend_yield}%"),
|
||||
("Beta", info.get("beta")),
|
||||
("52 Week High", info.get("fiftyTwoWeekHigh")),
|
||||
("52 Week Low", info.get("fiftyTwoWeekLow")),
|
||||
("50 Day Average", info.get("fiftyDayAverage")),
|
||||
("200 Day Average", info.get("twoHundredDayAverage")),
|
||||
("Revenue (TTM)", info.get("totalRevenue")),
|
||||
("Gross Profit", info.get("grossProfits")),
|
||||
("EBITDA", info.get("ebitda")),
|
||||
("Net Income", info.get("netIncomeToCommon")),
|
||||
("52 Week High", money("fiftyTwoWeekHigh", quote)),
|
||||
("52 Week Low", money("fiftyTwoWeekLow", quote)),
|
||||
("50 Day Average", money("fiftyDayAverage", quote)),
|
||||
("200 Day Average", money("twoHundredDayAverage", quote)),
|
||||
("Revenue (TTM)", money("totalRevenue", reported)),
|
||||
("Gross Profit", money("grossProfits", reported)),
|
||||
("EBITDA", money("ebitda", reported)),
|
||||
("Net Income", money("netIncomeToCommon", reported)),
|
||||
("Profit Margin", info.get("profitMargins")),
|
||||
("Operating Margin", info.get("operatingMargins")),
|
||||
("Return on Equity", info.get("returnOnEquity")),
|
||||
@@ -71,8 +88,8 @@ def get_fundamentals(
|
||||
("Debt to Equity", None if debt_to_equity is None
|
||||
else f"{debt_to_equity}% ({debt_to_equity / 100:.2f}x)"),
|
||||
("Current Ratio", info.get("currentRatio")),
|
||||
("Book Value", info.get("bookValue")),
|
||||
("Free Cash Flow", info.get("freeCashflow")),
|
||||
("Book Value", money("bookValue", main)),
|
||||
("Free Cash Flow", money("freeCashflow", reported)),
|
||||
]
|
||||
|
||||
lines = [f"{label}: {v}" for label, v in fields if v is not None]
|
||||
|
||||
Reference in New Issue
Block a user