Merge pull request #2804 from dokson/feature/ticker-lang-region
Allow lang and region scoping for Ticker (closes #2582)
This commit is contained in:
@@ -54,3 +54,27 @@ Debug
|
||||
.. code-block:: python
|
||||
|
||||
yf.config.debug.logging = True
|
||||
|
||||
Locale
|
||||
------
|
||||
|
||||
Localized fields (``longName``, ``shortName``, ...) follow
|
||||
``yf.config.locale``. The default is ``en-US`` / ``US``. Switch the Yahoo
|
||||
locale once at session start and every subsequent v7 / v10 endpoint call
|
||||
(``Ticker.info``, ``Ticker.fast_info``, ``Ticker.calendar``,
|
||||
``earnings_dates``, ...) inherits it:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import yfinance as yf
|
||||
yf.config.locale.lang = "zh-Hant-HK"
|
||||
yf.config.locale.region = "HK"
|
||||
yf.Ticker("1810.HK").info["longName"] # → '小米集團-W'
|
||||
|
||||
yf.config.locale.lang = "ja-JP"
|
||||
yf.config.locale.region = "JP"
|
||||
yf.Ticker("7203.T").info["longName"] # → 'トヨタ自動車'
|
||||
|
||||
Yahoo only returns translated values for tickers natively listed in that
|
||||
locale; ``Ticker("AAPL")`` keeps returning ``"Apple Inc."`` under
|
||||
``ja-JP``.
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
"""Verify YfConfig.locale switches the lang/region forwarded to Yahoo."""
|
||||
from tests.context import yfinance as yf
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class TestTickerLocale(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._backup_lang = yf.config.locale.lang
|
||||
self._backup_region = yf.config.locale.region
|
||||
|
||||
def tearDown(self):
|
||||
yf.config.locale.lang = self._backup_lang
|
||||
yf.config.locale.region = self._backup_region
|
||||
|
||||
def test_default_locale_is_en_us(self):
|
||||
self.assertEqual(yf.config.locale.lang, "en-US")
|
||||
self.assertEqual(yf.config.locale.region, "US")
|
||||
|
||||
def test_default_returns_english(self):
|
||||
# Default locale (en-US/US) returns the U.S. English long name.
|
||||
self.assertEqual(yf.Ticker("1810.HK").info["longName"], "Xiaomi Corporation")
|
||||
|
||||
def test_locale_zh_hant_hk(self):
|
||||
yf.config.locale.lang = "zh-Hant-HK"
|
||||
yf.config.locale.region = "HK"
|
||||
# 小米集團-W
|
||||
self.assertEqual(yf.Ticker("1810.HK").info["longName"], "小米集團-W")
|
||||
|
||||
def test_locale_ja_jp(self):
|
||||
yf.config.locale.lang = "ja-JP"
|
||||
yf.config.locale.region = "JP"
|
||||
# トヨタ自動車
|
||||
self.assertEqual(yf.Ticker("7203.T").info["longName"], "トヨタ自動車")
|
||||
|
||||
def test_locale_ru_ru(self):
|
||||
yf.config.locale.lang = "ru-RU"
|
||||
yf.config.locale.region = "RU"
|
||||
# Публичное акционерное общество Газпром
|
||||
name = yf.Ticker("GAZP.ME").info.get("longName")
|
||||
if name is None:
|
||||
self.skipTest("GAZP.ME longName unavailable from Yahoo")
|
||||
self.assertIn("Газпром", name) # contains "Газпром"
|
||||
|
||||
def test_locale_us_listing_not_translated(self):
|
||||
# Yahoo only translates fields for natively-listed companies.
|
||||
# Apple's U.S. listing has no Japanese translation.
|
||||
yf.config.locale.lang = "ja-JP"
|
||||
yf.config.locale.region = "JP"
|
||||
self.assertEqual(yf.Ticker("AAPL").info["longName"], "Apple Inc.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+1
-1
@@ -738,7 +738,7 @@ class TickerBase:
|
||||
|
||||
# Fetch data
|
||||
url = f"{_QUERY1_URL_}/v1/finance/visualization"
|
||||
params = {"lang": "en-US", "region": "US"}
|
||||
params = {"lang": YfConfig.locale.lang, "region": YfConfig.locale.region}
|
||||
body = {
|
||||
"size": limit,
|
||||
"query": { "operator": "eq", "operands": ["ticker", self.ticker] },
|
||||
|
||||
@@ -33,6 +33,9 @@ class ConfigMgr:
|
||||
d = self.__getattr__('debug')
|
||||
d.hide_exceptions = True
|
||||
d.logging = False
|
||||
loc = self.__getattr__('locale')
|
||||
loc.lang = "en-US" # BCP-47 language tag for Yahoo v7/v10 endpoints
|
||||
loc.region = "US" # ISO 3166-1 alpha-2 country code
|
||||
|
||||
def __getattr__(self, key):
|
||||
if not self._initialised:
|
||||
|
||||
@@ -591,7 +591,7 @@ class Quote:
|
||||
modules = ','.join([m for m in modules if m in quote_summary_valid_modules])
|
||||
if len(modules) == 0:
|
||||
raise YFException("No valid modules provided, see available modules using `valid_modules`")
|
||||
params_dict = {"modules": modules, "corsDomain": "finance.yahoo.com", "formatted": "false", "symbol": self._symbol}
|
||||
params_dict = {"modules": modules, "corsDomain": "finance.yahoo.com", "formatted": "false", "symbol": self._symbol, "lang": YfConfig.locale.lang, "region": YfConfig.locale.region}
|
||||
try:
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_ + f"/{self._symbol}", params=params_dict)
|
||||
except curl_cffi.requests.exceptions.HTTPError as e:
|
||||
@@ -602,7 +602,7 @@ class Quote:
|
||||
return result
|
||||
|
||||
def _fetch_additional_info(self):
|
||||
params_dict = {"symbols": self._symbol, "formatted": "false"}
|
||||
params_dict = {"symbols": self._symbol, "formatted": "false", "lang": YfConfig.locale.lang, "region": YfConfig.locale.region}
|
||||
try:
|
||||
result = self._data.get_raw_json(f"{_QUERY1_URL_}/v7/finance/quote?", params=params_dict)
|
||||
except curl_cffi.requests.exceptions.HTTPError as e:
|
||||
|
||||
Reference in New Issue
Block a user