Commit Graph

227 Commits

Author SHA1 Message Date
Alessandro Colace c3db565d09 Preserve Date/Datetime index name in yf.download() output
reindex_dfs() rebuilt the combined index via sorted(set(...)) +
pd.to_datetime, dropping the index name set by history.py ('Date' for
daily, 'Datetime' for intraday). After concat, data.index.name was
None, so users doing data.stack().reset_index() got a 'level_0' column
instead of 'Date' / 'Datetime'.

Use Index.union, which preserves the name natively when sources agree.

Drive-by: narrow data.columns to MultiIndex before swaplevel to silence
a pyright attribute warning.
2026-05-25 22:20:29 +02:00
ValueRaider 54bef21e98 Fix tests 2026-05-23 14:46:39 +01:00
ValueRaider 9ca1c55b12 Merge pull request #2802 from dokson/feature/optional-curl-cffi
Make curl_cffi optional with fallback to requests (closes #2692)
2026-05-20 21:34:45 +01:00
Alessandro Colace 5d10c0c48e Make curl_cffi optional with graceful fallback to requests
Some platforms (e.g. older macOS, exotic Linux distros) cannot build the
curl-impersonate binary that backs curl_cffi, leaving yfinance unusable.
This change keeps curl_cffi as the preferred and default backend but no
longer hard-requires it at runtime.

- New `yfinance/_http.py` abstracts the HTTP backend. If `curl_cffi` is
  importable it is used as before; otherwise yfinance falls back to plain
  `requests` with a realistic Chrome User-Agent and logs a warning so the
  downgrade is explicit.
- `data.py`, `base.py`, `multi.py`, `scrapers/history.py` build sessions
  via `_http.new_session()`.
- Scrapers and screener catch `_http.HTTPError` instead of importing
  `curl_cffi.requests.exceptions.HTTPError` directly.
- `is_supported_session()` accepts either backend; `cookie_jar()` papers
  over the small API difference between curl_cffi (`cookies.jar`) and
  requests (`cookies` is itself the jar).
- New Advanced > Installation page documents the curl_cffi-free install
  recipe; README links to it just under the install instruction.

Empirically verified that plain `requests` with a Chrome UA does not hit
the 401-after-~10-requests issue that the earlier `curl_adapter` approach
ran into; 15/15 quoteSummary calls succeed without rate limiting.

`setup.py` is unchanged -- `curl_cffi>=0.15` remains the default install
requirement (CVE-pinned). The fallback only activates when the import
fails at runtime; moving curl_cffi to extras_require can be a follow-up
decision for the maintainer.
2026-05-20 14:17:02 +02:00
Alessandro Colace 593b47c36d Drop frozendict hard dependency in favour of an internal fallback 2026-05-20 14:08:25 +02:00
ValueRaider 46ce563111 Merge pull request #2804 from dokson/feature/ticker-lang-region
Allow lang and region scoping for Ticker (closes #2582)
2026-05-17 20:16:57 +01:00
Alessandro Colace 97bdabe9dc Allow lang and region scoping for Ticker via YfConfig
Yahoo's v7 (`/v7/quote`) and v10 (`/quoteSummary`) endpoints accept
`lang` and `region` parameters and return localized fields (`longName`,
`shortName`, ...) when the ticker has been translated for that locale —
e.g. 1810.HK returns '小米集團-W' under `lang=zh-Hant-HK`, GAZP.ME
returns 'Публичное акционерное общество Газпром' under `lang=ru-RU`.
Previously these params were not exposed and `Ticker.info["longName"]`
always came back in U.S. English.

Surfaced as global config (`YfConfig.locale.lang` / `YfConfig.locale.region`)
rather than per-Ticker constructor params: a typical user wants the
same locale for every call in their session, and the config approach
also covers the v10 calendar/earnings endpoint in `_fetch_history_metadata`
without threading kwargs through three layers.

- Add `YfConfig.locale.lang` (default `"en-US"`) and `YfConfig.locale.region`
  (default `"US"`).
- `Quote._fetch` (v10/quoteSummary) and `Quote._fetch_additional_info`
  (v7/quote) read the locale from `YfConfig` on every call.
- `_fetch_history_metadata` (v1 calendar) reads the same locale, replacing
  a hardcoded `lang=en-US, region=US`.
- The `v8/chart` endpoint ignores `lang` server-side, so we don't forward
  there — would only generate noise.
- Verified live for Latin/diacritics (it-IT), CJK (zh-Hant-HK, ja-JP),
  Cyrillic (ru-RU); Apple under ja-JP correctly stays "Apple Inc." since
  it's a U.S. listing.

Closes #2582
2026-05-15 17:13:22 +02:00
ValueRaider 80e7cbda97 Merge pull request #2805 from dokson/fix/download-thread-safety
Make yf.download() reentrant by removing shared module globals
2026-05-14 22:14:29 +01:00
Alessandro Colace a710ba8340 Make yf.download() reentrant by removing shared module globals
`download()` used module-level dicts in `yfinance.shared` (`_DFS`,
`_ERRORS`, `_TRACEBACKS`, `_ISINS`) as scratch space. Concurrent calls
trampled each other; the previous fix wrapped the whole call in
`shared._LOCK`, which silently serialized parallel downloads — hiding
the race instead of removing it, and defeating the parallelism users
reach for `download()` to get.

- Introduce `_DownloadCtx` per call holding `dfs/errors/tracebacks/isins`
  plus a fine-grained lock for thread workers.
- `_download_one`, `_download_one_threaded`, `_realign_dfs` take the ctx
  explicitly and write into it.
- Drop the call-wide `shared._LOCK.acquire()`; concurrent `download()`
  calls now actually run in parallel. The polling loop on the threaded
  path reads `len(ctx.dfs)` under the ctx lock.
- `PriceHistory` records soft errors (delisted, missing tz, repair
  failure) in `self._last_error` instead of `shared._ERRORS`; the
  download loop reads it after `Ticker.history()` returns.
- `yfinance.shared` is left in place for import-compat with code that
  may still import it, but yfinance no longer reads or writes it.
- Update existing test_multi to the new `_download_one(ctx, ...)`
  signature and add regression tests covering result separation,
  no-raise on concurrent calls, and a sentinel proving `shared._DFS`
  is no longer used as scratch space.
2026-05-09 18:47:53 +02:00
Alessandro Colace ac1a7f65ca Allow region scoping for Sector and Industry
Yahoo's `/v1/finance/sectors/{key}` and `/industries/{key}` endpoints accept
an ISO 3166-1 alpha-2 `region` query parameter and return regional top
companies/ETFs/funds accordingly. The Domain base class hard-coded `region=US`,
so `Sector("technology").top_companies` always returned U.S. names regardless
of the user's interest.

- Add `region: str = "US"` to `Domain.__init__` and propagate through
  `Sector` and `Industry`.
- Normalize input via `.strip().upper()` so "us", " GB ", and "Fr" all work.
- Use `self._region` in the request params.
- Document and test the behavior.

Closes #2601
2026-05-09 17:55:05 +02:00
Alessandro Colace 90c267103a Validate Market region and stop returning misleading status data
Yahoo's markettime endpoint silently ignores the `market` parameter and
always returns U.S. data, so `Market("EUROPE").status` previously returned
U.S. status while pretending to be European. The summary endpoint does
honor the parameter and is unaffected.

- Introduce `MarketRegion(str, Enum)` as the single source of truth for
  the supported region values, exposed as `yfinance.MarketRegion`.
- Validate `Market(...)` input against the enum and raise `ValueError`
  on unknown regions.
- Detect the markettime mismatch: when a non-`US` region is requested
  but the response id is `us`, set `status` to `None` and log a warning
  rather than returning misleading data.
- Document the markettime limitation and add tests covering validation
  and the EUROPE/US fetch behavior.

Closes #2784
2026-05-09 13:33:50 +02:00
ValueRaider 7cd4735e0d Fix dividends error on unlisted tickers 2026-05-05 22:04:58 +01:00
ValueRaider 65b8b6ba19 Merge pull request #2792 from etbala/fix-tests
Fix Failing Tests
2026-04-30 21:09:21 +01:00
etbala 866db49d34 fix failing tests 2026-04-29 18:04:01 -05:00
Jaypatel1511 212a5eaf3a Move chart-None regression test into test_prices.py (#2670)
Use yf.Ticker().history() convention consistent with the rest of test_prices.py.
Remove standalone test_chart_none_guard.py file.
2026-04-29 17:06:37 -05:00
Jaypatel1511 2378a5fc09 Fix NoneType crash when data['chart'] is None (issue #2670)
Guard both chart-error and chart-result checks against data['chart']
being None, which previously raised TypeError instead of the expected
YFPricesMissingError.

- history.py L270: add 'data["chart"]' truthiness check before accessing ['error']
- history.py L274: add 'not data["chart"]' short-circuit before accessing ['result']
- Add regression test covering chart=None, result=None, missing key, and error payload
2026-04-29 16:57:17 -05:00
gottostartsomewhere 040e617041 Fix: _dts_in_same_interval("1mo") ignored year, treating same-month in different years as the same interval
The "1mo" branch compared only `dt1.month == dt2.month`, so e.g.
(2024-12-15, 2025-12-15) returned True. The "3mo" branch already
handles year differences via `year_diff`; mirror that by also
requiring `dt1.year == dt2.year`.

Added a test (`test_same_month_different_year`) that fails on the
old logic and passes on the fix. All existing tests still pass.
2026-04-24 11:24:16 +05:30
ValueRaider 9b79ef76bf Add 'repair' to get_history_metadata() 2026-04-23 20:47:45 +01:00
Ethan Balakumar eac7f2ffa9 Add valuation measures 2026-04-13 20:16:16 -05:00
Carson Jones 27589a1539 Add mutex lock to prevent concurrent download() corruption
Concurrent calls to yf.download() from separate threads share the
module-level _DFS, _ERRORS, and _TRACEBACKS dicts, causing one call
to overwrite or read another's results. Serialize access with a
threading.Lock so each download() runs atomically.

Fixes #2557
2026-03-12 17:05:08 -04:00
ValueRaider 7874a45e3b Merge pull request #2682 from ranaroussi/dev
sync dev -> main
2026-01-24 15:57:45 +00:00
Carlos-Tasada 25bf12cb92 Upgrade to Pandas 3.0 (Fixes #2679)
Pandas 3.0 introduced many changes. One of them is a noisy deprecation warning `Pandas4Warning: Timestamp.utcnow is deprecated and will be removed in a future version. Use Timestamp.now('UTC') instead.`

This PR upgrades YFinance to use the latest Pandas 3.0.0 version, removing the warning
2026-01-23 08:44:47 +01:00
ValueRaider 27cb8aa2a2 Docs for capital-gains repair; Fix warnings in price-repair 2026-01-22 19:36:37 +00:00
ValueRaider bf94ae937b Merge pull request #2668 from ranaroussi/fix/price-split-repair-false-positives
Improve stock-split repair false-positives
2026-01-19 23:11:02 +00:00
ValueRaider ce4c07be1f New price repair: capital gains double-counting 2026-01-19 23:10:05 +00:00
ValueRaider f984876b35 Improve stock-split repair false-positives 2026-01-19 23:09:16 +00:00
ValueRaider 4f38ecfea0 Redesign YfConfig + small fixes
Fixes:
- earnings_dates caching
- _resample on period=ytd

New deprecations:
- yf.set_config()
- move enable_debug_mode() to YfConfig

Complete deprecations:
- proxy arguments
- download(auto_adjust)

Small test fixes
2025-12-20 16:23:20 +00:00
ValueRaider 39c2f76c1a Merge pull request #2615 from ianmihura/feature/earnings-calendar
Feature: Earning Calendar (& other calendars)
2025-12-10 21:52:45 +00:00
Ian Mihura 428919b701 earning calendar and other calendars 2025-12-10 17:55:42 +01:00
aivibe ec5f1c2470 Add optional retry mechanism for transient network errors 2025-12-02 06:23:26 +07:00
ValueRaider 2e0ad642c1 Merge pull request #2579 from mxdev88/main
feat: add market_suffix
2025-08-17 16:20:16 +01:00
ValueRaider 54b37a403c reduce code diff 2025-08-17 16:09:00 +01:00
mxdev88 a04a4ea475 feat: add market_suffix 2025-08-06 09:56:39 +02:00
ValueRaider 9f0d3fd12d Merge pull request #2580 from skyblue6688/bug-fix-2576
Fix test_ticker unit test failure due to NEPT delisting
2025-08-04 19:02:06 +01:00
jdmcclain47 4259760bea Fix internal parsing of epochs and add tests 2025-08-03 21:19:08 -05:00
Shi Qin 9a6c82aea6 Fix test_ticker unit test failure due to NEPT delisting 2025-08-03 14:52:50 -07:00
ValueRaider 8db46f2b12 Fix a test 2025-07-06 17:16:37 +01:00
ValueRaider a9282e5739 Fix ruff 2025-05-17 11:25:10 +01:00
ValueRaider f716eec5fe Little fixes for tests & proxy msg 2025-05-14 21:41:17 +01:00
Dhruvan Gnanadhandayuthapani fc5d29558b Add WebSocket support 2025-04-27 20:39:20 +02:00
ValueRaider fee9af07ce Fix tests and a typo 2025-04-23 21:46:36 +01:00
ValueRaider cfc7142c56 Merge pull request #2391 from ranaroussi/feature/config
Config
2025-04-01 19:36:44 +01:00
ValueRaider 89f1934bd6 Config 1st version: just proxy 2025-03-31 19:06:43 +01:00
ValueRaider 07651ed2f4 Merge pull request #2389 from ranaroussi/fix/prices-live-combine
Fix fix_Yahoo_returning_live_separate()
2025-03-31 19:06:06 +01:00
ValueRaider b1bb75113c Merge pull request #2364 from dhruvan2006/feature/lookup
Feature: Ticker lookups
2025-03-30 21:26:57 +01:00
ValueRaider fbe9f8f119 Fix fix_Yahoo_returning_live_separate()
Was not handling live row on/just-after New Years.
Also fixed prepost interval being merged, incorrectly.
2025-03-30 20:38:11 +01:00
Jan Melen 00fec80f63 Merge branch 'dev' into fix-issue-2301 2025-03-30 09:02:59 +03:00
Jan Melen 81c6b2d2e6 Fixes issues 2301 and 2383 AttributeError
- In utils.py line 165 if the session is None then _requests is
  mistakenly passed to as session to data.py which causes attribute
  error: module 'requests.cookies' has no attribute 'update'
- The above condition happens only when searching tickers with ISIN
  numbers
- Added tests with ISIN numbers
- Added tickerBase to raise an ValueError if an empty tickername is
  passed or isin search results in to empty ticker. This is to have
  consistent behaviour with utils.get_all_by_isin()
- Corrected ruff check failures
- Rebasing to latest upstream/dev
- Updated the value error to contain the ISIN number that wasn't found
2025-03-26 23:57:00 +02:00
Jan Melen 587fdd032b Fixes issue 2343 and 2363 Empty result and QuoteResponse
- Check that if result from _fetch was None and either update the result
  with additional info or set the result as the additional info.
- Added test_empty_info test case to protect if the behavior in Yahoo
  changes.
- Fixed typo on line 1024
2025-03-26 06:26:28 +02:00
Dhruvan Gnanadhandayuthapani 8908724f3c Add Lookup module documentation and examples 2025-03-23 15:06:17 +01:00