Skip to content

Commit

Permalink
Merge branch 'main' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ValueRaider authored Aug 13, 2023
2 parents 677f3d5 + 5b0cb60 commit c9dd582
Show file tree
Hide file tree
Showing 20 changed files with 355 additions and 101 deletions.
44 changes: 0 additions & 44 deletions .github/ISSUE_TEMPLATE/bug_report.md

This file was deleted.

88 changes: 88 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
name: Bug report
description: Report a bug in our project
labels: ["bug"]

body:
- type: markdown
attributes:
value: |
# IMPORTANT - Read and follow these instructions carefully. Help us help you.
### Does issue already exist?
Use the search tool. Don't annoy everyone by duplicating existing Issues.
### Are you up-to-date?
Upgrade to the latest version and confirm the issue/bug is still there.
`$ pip install yfinance --upgrade --no-cache-dir`
Confirm by running:
`import yfinance as yf ; print(yf.__version__)`
and comparing against [PIP](https://pypi.org/project/yfinance/#history).
### Does Yahoo actually have the data?
Are you spelling symbol *exactly* same as Yahoo?
Then visit `finance.yahoo.com` and confirm they have the data you want. Maybe your symbol was delisted, or your expectations of `yfinance` are wrong.
### Are you spamming Yahoo?
Yahoo Finance free service has rate-limiting https://github.com/ranaroussi/yfinance/discussions/1513. Once limit hit, Yahoo can delay, block, or return bad data -> not a `yfinance` bug.
- type: markdown
attributes:
value: |
---
## Still think it's a bug?
Provide the following as best you can:
- type: textarea
id: code
attributes:
label: "Simple code that reproduces your problem"
description: "Provide a snippet of code that we can copy-paste-run. Wrap code in Python Markdown code blocks for proper formatting (```` ```python ... ``` ````)."
validations:
required: true

- type: textarea
id: debug-log
attributes:
label: "Debug log"
description: "Run code with debug logging enabled and post the full output. Instructions: https://github.com/ranaroussi/yfinance/tree/main#logging"
validations:
required: true

- type: textarea
id: bad-data-proof
attributes:
label: "Bad data proof"
description: "If you think `yfinance` returning bad data, provide your proof here."
validations:
required: false

- type: input
id: version-yfinance
attributes:
label: "`yfinance` version"
validations:
required: true

- type: input
id: version-python
attributes:
label: "Python version"
validations:
required: false

- type: input
id: os
attributes:
label: "Operating system"
validations:
required: false
17 changes: 17 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
Change Log
===========

0.2.27
------
Bug fixes:
- fix merging 1d-prices with out-of-range divs/splits #1635
- fix multithread error 'tz already in cache' #1648

0.2.26
------
Proxy improvements
- bug fixes #1371
- security fix #1625

0.2.25
------
Fix single ISIN as ticker #1611
Fix 'Only 100 years allowed' error #1576

0.2.24
------
Fix info[] missing values #1603
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,13 @@ To install `yfinance` using `conda`, see
- [Python](https://www.python.org) \>= 2.7, 3.4+
- [Pandas](https://github.com/pydata/pandas) \>= 1.3.0
- [Numpy](http://www.numpy.org) \>= 1.16.5
- [requests](http://docs.python-requests.org/en/master) \>= 2.26
- [requests](http://docs.python-requests.org/en/master) \>= 2.31
- [lxml](https://pypi.org/project/lxml) \>= 4.9.1
- [appdirs](https://pypi.org/project/appdirs) \>= 1.4.4
- [pytz](https://pypi.org/project/pytz) \>=2022.5
- [frozendict](https://pypi.org/project/frozendict) \>= 2.3.4
- [beautifulsoup4](https://pypi.org/project/beautifulsoup4) \>= 4.11.1
- [html5lib](https://pypi.org/project/html5lib) \>= 1.1
- [cryptography](https://pypi.org/project/cryptography) \>= 3.3.2

#### Optional (if you want to use `pandas_datareader`)

Expand Down
8 changes: 3 additions & 5 deletions meta.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% set name = "yfinance" %}
{% set version = "0.2.24" %}
{% set version = "0.2.27" %}

package:
name: "{{ name|lower }}"
Expand All @@ -18,7 +18,7 @@ requirements:
host:
- pandas >=1.3.0
- numpy >=1.16.5
- requests >=2.26
- requests >=2.31
- multitasking >=0.0.7
- lxml >=4.9.1
- appdirs >=1.4.4
Expand All @@ -27,14 +27,13 @@ requirements:
- beautifulsoup4 >=4.11.1
- html5lib >=1.1
# - pycryptodome >=3.6.6
- cryptography >=3.3.2
- pip
- python

run:
- pandas >=1.3.0
- numpy >=1.16.5
- requests >=2.26
- requests >=2.31
- multitasking >=0.0.7
- lxml >=4.9.1
- appdirs >=1.4.4
Expand All @@ -43,7 +42,6 @@ requirements:
- beautifulsoup4 >=4.11.1
- html5lib >=1.1
# - pycryptodome >=3.6.6
- cryptography >=3.3.2
- python

test:
Expand Down
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
pandas>=1.3.0
numpy>=1.16.5
requests>=2.26
requests>=2.31
multitasking>=0.0.7
lxml>=4.9.1
appdirs>=1.4.4
pytz>=2022.5
frozendict>=2.3.4
beautifulsoup4>=4.11.1
html5lib>=1.1
cryptography>=3.3.2
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
keywords='pandas, yahoo finance, pandas datareader',
packages=find_packages(exclude=['contrib', 'docs', 'tests', 'examples']),
install_requires=['pandas>=1.3.0', 'numpy>=1.16.5',
'requests>=2.26', 'multitasking>=0.0.7',
'requests>=2.31', 'multitasking>=0.0.7',
'lxml>=4.9.1', 'appdirs>=1.4.4', 'pytz>=2022.5',
'frozendict>=2.3.4',
'beautifulsoup4>=4.11.1', 'html5lib>=1.1'],
Expand Down
9 changes: 9 additions & 0 deletions tests/prices.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,15 @@ def test_dailyWithEvents_bugs(self):
print("{}-without-events missing these dates: {}".format(tkr, missing_from_df2))
raise

# Reproduce issue #1634 - 1d dividend out-of-range, should be prepended to prices
div_dt = _pd.Timestamp(2022, 7, 21).tz_localize("America/New_York")
df_dividends = _pd.DataFrame(data={"Dividends":[1.0]}, index=[div_dt])
df_prices = _pd.DataFrame(data={c:[1.0] for c in yf.const.price_colnames}|{'Volume':0}, index=[div_dt+_dt.timedelta(days=1)])
df_merged = yf.utils.safe_merge_dfs(df_prices, df_dividends, '1d')
self.assertEqual(df_merged.shape[0], 2)
self.assertTrue(df_merged[df_prices.columns].iloc[1:].equals(df_prices))
self.assertEqual(df_merged.index[0], div_dt)

def test_intraDayWithEvents(self):
tkrs = ["BHP.AX", "IMP.JO", "BP.L", "PNL.L", "INTC"]
test_run = False
Expand Down
125 changes: 125 additions & 0 deletions tests/ticker.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class TestTicker(unittest.TestCase):
def setUpClass(cls):
cls.session = session_gbl

cls.proxy = None

@classmethod
def tearDownClass(cls):
if cls.session is not None:
Expand Down Expand Up @@ -144,6 +146,129 @@ def test_goodTicker(self):
# dat.earnings_trend
# dat.earnings_forecasts

def test_goodTicker_withProxy(self):
# that yfinance works when full api is called on same instance of ticker

tkr = "IBM"
dat = yf.Ticker(tkr, session=self.session)

dat._fetch_ticker_tz(proxy=self.proxy, timeout=5, debug_mode=False, raise_errors=False)
dat._get_ticker_tz(proxy=self.proxy, timeout=5, debug_mode=False, raise_errors=False)
dat.history(period="1wk", proxy=self.proxy)

v = dat.stats(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertTrue(len(v) > 0)

v = dat.get_recommendations(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_calendar(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_major_holders(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_institutional_holders(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_mutualfund_holders(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_info(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertTrue(len(v) > 0)

v = dat.get_sustainability(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_recommendations_summary(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_analyst_price_target(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_rev_forecast(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_earnings_forecast(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_trend_details(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_earnings_trend(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_earnings(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_income_stmt(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_incomestmt(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_financials(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_balance_sheet(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_balancesheet(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_cash_flow(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_cashflow(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_shares(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_shares_full(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

v = dat.get_isin(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertTrue(v != "")

v = dat.get_news(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertTrue(len(v) > 0)

v = dat.get_earnings_dates(proxy=self.proxy)
self.assertIsNotNone(v)
self.assertFalse(v.empty)

# TODO: enable after merge
# dat.get_history_metadata(proxy=self.proxy)
# self.assertIsNotNone(v)
# self.assertTrue(len(v) > 0)


class TestTickerHistory(unittest.TestCase):
session = None
Expand Down
Loading

0 comments on commit c9dd582

Please sign in to comment.