Compare commits

..

299 Commits

Author SHA1 Message Date
ValueRaider
dfffa6a551 Bump version to 0.1.96 2022-12-20 20:50:01 +00:00
ValueRaider
787b89c269 Merge pull request #1258 from ranaroussi/r0.1/fix/info-not-caching
Another info[] fix for #1256
2022-12-20 20:48:27 +00:00
ValueRaider
882f8b3367 Another info[] fix for #1256 2022-12-19 22:50:12 +00:00
ValueRaider
338a94a8f3 Bump version to 0.1.95 2022-12-19 21:46:58 +00:00
ValueRaider
e108a543fa Merge pull request #1257 from ranaroussi/r0.1/fix/quotes-html-parsing
Fix quotes html parsing when missing root.App.main
2022-12-19 21:43:42 +00:00
ValueRaider
071c3937b5 Add 'G7W.DU' to test 2022-12-19 16:48:10 +00:00
ValueRaider
a279d06810 Fix quotes html parsing when missing root.App.main 2022-12-19 16:18:43 +00:00
ValueRaider
80db9dfe3c Bump version to 0.1.94 2022-12-19 11:17:51 +00:00
ValueRaider
6bb23e05c2 Fix delisted ticker info[] 2022-12-19 11:16:45 +00:00
ValueRaider
edf2f69b62 Bump version to 0.1.93 2022-12-18 22:16:28 +00:00
ValueRaider
ce4c2e457d Fix Ticker.shares 2022-12-18 22:15:44 +00:00
ValueRaider
4fc15251a0 Bump version to 0.1.92 2022-12-18 21:45:07 +00:00
ValueRaider
c4600d6bd9 Fix setup.py 2022-12-18 21:44:30 +00:00
ValueRaider
14a839582d Bump version to 0.1.91 2022-12-18 21:39:08 +00:00
ValueRaider
3ae0434567 Merge pull request #1255 from ranaroussi/fix/decode-Yahoo-encryption
Backport Yahoo decryption
2022-12-18 21:37:26 +00:00
ValueRaider
f24dab2f26 Add 'cryptography' requirement 2022-12-18 21:35:07 +00:00
ValueRaider
b47adf0a90 Backport Yahoo decryption 2022-12-18 20:42:03 +00:00
ValueRaider
3537ec3e4b Bump version to 0.1.90 2022-12-13 15:36:36 +00:00
ValueRaider
6a306b0353 Merge pull request #1237 from ranaroussi/r0.1/fix/lxml
Restore lxml dep, set min ver = 4.9.1
2022-12-13 15:35:12 +00:00
ValueRaider
6e3282badb Restore lxml dep, set min ver = 4.9.1 2022-12-13 15:03:13 +00:00
ValueRaider
829683ca02 Bump version to 0.1.89 2022-12-12 22:06:28 +00:00
ValueRaider
3011cb324d Bump version to 0.1.88 2022-12-12 22:04:02 +00:00
ValueRaider
366cfc0795 Merge pull request #1231 from ranaroussi/r0.1/fix/reqs
Bump pandas to 1.3.0 ; Remove unused lxml
2022-12-10 18:17:51 +00:00
ValueRaider
cbd4b924b8 Bump pandas to 1.3.0 ; Remove unused lxml 2022-12-10 14:25:07 +00:00
ValueRaider
56759e3f3c Bump version to 0.1.87 2022-11-16 12:38:10 +00:00
ValueRaider
c193428b38 Merge pull request #1163 from ranaroussi/patch/threads-print-deadlock
Fix disable prints inside threads (bpython deadlock)
2022-11-16 12:36:48 +00:00
ValueRaider
a625d9e9c5 Merge pull request #1176 from ranaroussi/patch/dst-nonexistent
Fix localizing midnight when non-existent (DST)
2022-11-16 12:33:54 +00:00
ValueRaider
36e80a73f7 Fix localizing midnight when non-existent (DST) 2022-11-16 12:28:29 +00:00
ValueRaider
cdae1cf226 Bump version to 0.1.86 2022-11-14 12:49:43 +00:00
ValueRaider
bca569318e Merge pull request #1170 from ranaroussi/patch/default-start
Backport #1169 (default start)
2022-11-13 11:52:51 +00:00
ValueRaider
d11cd85a66 Backport #1169 (default start) 2022-11-13 11:51:41 +00:00
ValueRaider
2d32a6e204 Merge pull request #1162 from ranaroussi/patch/tz-csv-error
Fix corrupt tkr-tz-csv halting code
2022-11-10 21:51:10 +00:00
ValueRaider
bad6456a44 Fix disable prints inside threads (bpython deadlock) 2022-11-10 18:30:34 +00:00
ValueRaider
1687ae66ab Fix corrupt tkr-tz-csv halting code 2022-11-10 14:19:21 +00:00
ValueRaider
ddc34348d9 Merge pull request #1142 from ranaroussi/patch-0.1/delisted-tkr-errors
Improve handling delisted tickers
2022-11-03 22:56:16 +00:00
ValueRaider
1d74cfeb19 Merge pull request #1141 from ranaroussi/patch-0.1/trailing-peg-ratio
Move get 'trailingPegRatio' into _get_info(), simplify & optimise
2022-11-03 22:55:39 +00:00
ValueRaider
1589d07b56 Move get 'trailingPegRatio' into _get_info(), simplify & optimise 2022-11-03 22:53:04 +00:00
ValueRaider
d261237320 Improve handling delisted tickers 2022-11-03 22:49:12 +00:00
ValueRaider
66af3080dd Bump version to 0.1.85 2022-11-03 19:04:45 +00:00
ValueRaider
9d396b9559 Merge pull request #1135 from ranaroussi/patch/unknown-ticker-timezone
Backport ticker tz verification for nice error
2022-11-02 15:18:26 +00:00
ValueRaider
23b6ad12c1 Backport ticker tz verification for nice error 2022-10-31 21:14:50 +00:00
ValueRaider
22131e9fc7 Merge pull request #1124 from Jossan84/main
Bugfix: Get logo url when no website exists
2022-10-27 22:34:18 +01:00
ValueRaider
e99e61f95a Bump version to 0.1.84 2022-10-26 00:12:29 +01:00
ValueRaider
a3fe95ea27 Make tz-cache thread-safe 2022-10-26 00:09:23 +01:00
ValueRaider
000cb70bcb Bump version to 0.1.83 2022-10-25 23:23:32 +01:00
ValueRaider
c8d9d06e75 Expose _fetch_ticker_tz() arguments 2022-10-25 23:21:56 +01:00
ValueRaider
a5e07a0375 Bump version to 0.1.82 2022-10-25 23:15:48 +01:00
ValueRaider
a0a12bcf4c Backport _fetch_ticker_tz() 2022-10-25 23:07:48 +01:00
Ran Aroussi
c49cf626bb Update bug_report.md 2022-10-24 11:37:15 +01:00
Ran Aroussi
fa6f3fc537 Update bug_report.md 2022-10-24 11:37:03 +01:00
ValueRaider
34dfe944d9 Bump version to 0.1.81 2022-10-23 19:54:28 +01:00
ValueRaider
9619839bf5 Merge pull request #1108 from ranaroussi/hotfix/cache-on-read-only-system
Fix cache error on read only system
2022-10-23 19:52:41 +01:00
ValueRaider
90e00a71ca Fix missing 'return' 2022-10-23 19:51:09 +01:00
ValueRaider
f525ee2f5e Add README section on tz-cache ; Add set_tz_cache_location() 2022-10-23 19:47:22 +01:00
ValueRaider
ef12c8b600 Catch read-only exceptions during cache write 2022-10-23 19:29:54 +01:00
ValueRaider
42e6d0894e Bump version to 0.1.80 2022-10-22 13:25:59 +01:00
ValueRaider
de1c3c091b Merge pull request #1103 from ranaroussi/hotfix/download-timezones-patch
Fix download(ignore_tz=True) for single ticker
2022-10-22 13:15:52 +01:00
ValueRaider
c6c0fa3347 Fix download(ignore_tz=True) for single ticker 2022-10-22 13:14:35 +01:00
ValueRaider
75c823a72c Merge pull request #1101 from ranaroussi/hotfix/tz-dst-ambiguous
Fix tz-localize when DST-ambiguous
2022-10-21 15:29:52 +01:00
ValueRaider
f1ad8f0061 Fix tz-localize when DST-ambiguous 2022-10-21 12:43:50 +01:00
ValueRaider
b27cc0cf40 Update to 0.1.79 2022-10-18 20:07:40 +01:00
ValueRaider
1d7f8139d6 Fix when Yahoo returns price=NaNs on dividend day 2022-10-18 20:04:08 +01:00
ValueRaider
01ef1bb813 Update to 0.1.78 2022-10-18 12:53:22 +01:00
ValueRaider
1db6be75b8 Merge pull request #1093 from ranaroussi/fix/download-timezones
Add 'ignore_tz' arg to download()
2022-10-18 12:36:00 +01:00
ValueRaider
7902ec8667 Fix empty-df detection and date ordering 2022-10-18 12:31:51 +01:00
ValueRaider
ff42a3ac87 Add 'ignore_tz' arg to download() 2022-10-18 12:22:43 +01:00
ValueRaider
51f2c7301d Bump version again to 0.1.77 to skip bad tag 2022-10-07 22:04:16 +01:00
ValueRaider
632a16670a Bump version to 0.1.76 2022-10-07 21:55:15 +01:00
ValueRaider
fea0dca6f4 Merge pull request #1078 from ranaroussi/fix/info-access-when-unlisted
Fix/info access when unlisted
2022-10-07 21:44:44 +01:00
ValueRaider
c7e95152a0 Tidy code 2022-10-07 17:23:59 +01:00
ValueRaider
a52e972d04 Pretty error check for timezone retrieval 2022-10-07 17:20:58 +01:00
Ran Aroussi
a197d9f78e updated changelog 2022-10-04 12:09:19 +01:00
Ran Aroussi
dbb9bbfbf3 Updated to 0.1.75 2022-10-04 12:01:30 +01:00
ValueRaider
a7b053addd Merge pull request #1067 from ranaroussi/fix/deps
Add new dep 'appdirs' for recent tz-fixes PR
2022-10-01 13:52:10 +01:00
ValueRaider
e8ca256c10 Add new dep 'appdirs' for recent tz-fixes PR 2022-10-01 13:49:02 +01:00
ValueRaider
f651dd1e93 Merge pull request #1048 from yfinance-fork-team/fix/timezone
Fix timezone & datetime handling
2022-09-21 16:53:29 +01:00
ValueRaider
f40cf0aae1 Merge branch 'main' into fix/timezone 2022-09-20 23:28:17 +01:00
ValueRaider
200f57c458 Merge pull request #1033 from yfinance-fork-team/fix/yahoo-appending-latest-price
Bugfix: Relocate out-of-range check to before 15m->30m conversion
2022-09-20 20:24:13 +01:00
ValueRaider
e5d45eaa85 Merge pull request #1032 from yfinance-fork-team/feature/keep-na
Add 'keepna' argument
2022-09-20 14:17:34 +01:00
ValueRaider
42b77a9b54 Merge pull request #1042 from yfinance-fork-team/feature/init-perf-boost
Ticker.init() perf boost
2022-09-20 14:15:50 +01:00
Jose Manuel
42e5751705 Bugfix: Get logo url when no website exists 2022-09-19 13:54:56 +02:00
ValueRaider
bca005a2c0 Move user dt parsing to utils.py 2022-09-04 17:45:37 +01:00
ValueRaider
ca891bb187 Restore index to DatetimeIndex ; remove tz arg ; refactor for clean merge 2022-09-04 16:09:55 +01:00
Value Raider
0939ff3c78 Support user providing epoch ints 2022-08-15 16:04:46 +01:00
Value Raider
6f5c5635be Preemptive bugfix 2022-07-28 12:30:13 +01:00
Value Raider
809622e426 Ticker init does unnecessary work - move it out 2022-07-28 12:25:43 +01:00
Value Raider
eec1f3dbad Fix when Yahoo messes up DST 2022-07-27 21:54:12 +01:00
Value Raider
1de789ad72 Fix timestamp->dt 2022-07-15 00:00:08 +01:00
Value Raider
cd68ff68c6 Adjust prices-after-end-dt fix from > to >= 2022-07-14 23:45:18 +01:00
Value Raider
9673970f45 Relocate out-of-range check to before 15m->30m interpolation 2022-07-14 23:04:41 +01:00
Value Raider
6ea69a70ac Add 'keepna' argument 2022-07-14 14:41:24 +01:00
Value Raider
c723a5ab44 Preemptive perf. boost 2022-07-14 01:03:24 +01:00
Value Raider
50741d1409 Add tz to daily/weekly - bugfix 2022-07-12 23:04:04 +01:00
Value Raider
69d0dcd62b Add tz to daily/weekly 2022-07-12 22:54:01 +01:00
Value Raider
5c9348f255 end time should default=00:00 not end-of-day - fix comment 2022-07-12 21:30:29 +01:00
Value Raider
a472546e7b end time should default=00:00 not end-of-day 2022-07-12 21:30:29 +01:00
Value Raider
c914f1f183 Fix user-supplied TZ ; reduce Git diff 2022-07-12 21:30:29 +01:00
Value Raider
92c82342fe Fix PYTZ misuse 2022-07-12 21:30:29 +01:00
Value Raider
7ae08b04f3 Fix setting end dt to midnight 2022-07-12 21:30:29 +01:00
Value Raider
4b50f1e81c Perf boost: store ticker timezone in user file cache 2022-07-12 21:30:29 +01:00
Value Raider
1ed58be749 Perf boost: separate info fetch from financials, to get tz fast 2022-07-12 21:30:28 +01:00
Value Raider
375b4f9376 Fix error when adding Dividends/Splits to df 2022-07-12 21:27:58 +01:00
Value Raider
b6b4426ca9 User-provided 'tz' should 'convert' not 'replace' UTC 2022-07-12 21:27:58 +01:00
Value Raider
149ebe46db Remove debugging print stmt 2022-07-12 21:27:58 +01:00
Value Raider
d80b27cfde Fix Yahoo returning tz in data 2022-07-12 21:27:58 +01:00
Value Raider
36e277317b Fix date->datetime conversion 2022-07-12 21:27:58 +01:00
Value Raider
0e1ea4d2c6 Replace zoneinfo with pytz (installed by pandas) 2022-07-12 21:27:58 +01:00
Value Raider
2d96c383ef Set start/end timezone to exchange if None 2022-07-12 21:27:57 +01:00
Ran Aroussi
ec6279736b Fixed bug introduced in 0.1.73 2022-07-11 23:20:47 +01:00
Ran Aroussi
5d942d9668 Update CHANGELOG.rst 2022-07-11 12:16:00 +01:00
Ran Aroussi
5782cb59fd Update version.py 2022-07-11 12:15:28 +01:00
Ran Aroussi
4c4861a8f1 Merge pull request #1000 from giorgossideris/shares_outstanding_none_values_bug_fix
Handle case that the API returns no data for shares of a specific year (#999)
2022-07-11 12:14:51 +01:00
Ran Aroussi
4d221ca70e Merge pull request #1009 from AndKraev/fix_724
rename incorrect yahoo key treasuryStock
2022-07-11 12:14:31 +01:00
Ran Aroussi
1a8d045baf Merge pull request #1023 from Ckend/main
bugfix: remove useless arg, otherwise affect the proxy arg.
2022-07-11 12:13:44 +01:00
Ran Aroussi
67a55c35ce Merge pull request #1024 from devpg/patch-1
Update multi.py
2022-07-11 12:13:21 +01:00
Ran Aroussi
e547fe4e41 Merge pull request #1026 from ValueRaider/fix/yahoo-appending-latest-price
Bug fix - Yahoo API appends latest price regardless of end date, remove it
2022-07-11 12:13:04 +01:00
Value Raider
9d5366d707 Bug fix - Yahoo API appends latest price regardless of end date, remove it 2022-07-09 18:35:12 +01:00
André Neubauer
4b07d1dceb Update multi.py
Documentation is wrong here. 'show_errors' does print errors if True, and doesn't print errors if False
2022-07-09 12:01:53 +02:00
ckend
9440c1e1c1 bugfix: remove useless arg, otherwise affect the proxy arg. 2022-07-08 17:53:54 +08:00
Ran Aroussi
773d003a67 Update CHANGELOG.rst 2022-06-16 16:32:33 +01:00
Ran Aroussi
a2905a0f8d Update version.py 2022-06-16 16:32:12 +01:00
Ran Aroussi
1810455e15 bugfix 2022-06-16 16:31:56 +01:00
Ran Aroussi
9770f286b4 v# + clog 2022-06-16 16:24:41 +01:00
Ran Aroussi
80eb0ddafb Merge branch 'main' of github.com:ranaroussi/yfinance 2022-06-16 16:17:16 +01:00
Ran Aroussi
a9e9e8dcb3 added Tickers(…).news() 2022-06-16 16:17:12 +01:00
Ran Aroussi
69c0673345 Merge pull request #959 from Kartheyan/patch-1
Fixed max period when interval is 1 minute
2022-06-16 16:16:53 +01:00
Ran Aroussi
8077cabf44 Merge branch 'main' of github.com:ranaroussi/yfinance 2022-06-16 16:04:32 +01:00
Ran Aroussi
e35b98ef1d pep stuff 2022-06-16 16:04:28 +01:00
Ran Aroussi
dc40c6d093 Merge pull request #955 from alker0/issue-677
Support cache in `Tickers()`
2022-06-16 16:04:20 +01:00
Ran Aroussi
8572628ba6 Merge pull request #1017 from ValueRaider/feature/earnings-dates
Feature - fetch full earnings dates history
2022-06-16 16:00:41 +01:00
Ran Aroussi
f878ce5ea5 Merge branch 'main' into feature/earnings-dates 2022-06-16 16:00:32 +01:00
Ran Aroussi
bbf68daf3f Merge pull request #1014 from rickturner2001/feature-earnings-history
Added get_earnings_history to fetch earnings data
2022-06-16 15:51:54 +01:00
Value Raider
afbb5d81a4 Tidy utils change 2022-06-16 12:12:04 +01:00
Value Raider
670ec8e766 Return empty DF if YF missing earnings dates 2022-06-16 12:08:16 +01:00
Value Raider
8fa9438072 Fix EPS % to 0->1 2022-06-16 12:07:15 +01:00
Value Raider
8c56a0c3df Fix timezone handling 2022-06-15 21:17:33 +01:00
Value Raider
6e90fc17cb Fix handling of missing data 2022-06-15 19:57:24 +01:00
Value Raider
0849f68dd8 Clean&format earnings_dates table 2022-06-15 19:36:54 +01:00
Value Raider
77f3810cdd Add feature get_earnings_dates() 2022-06-15 17:42:22 +01:00
rickturner01
f3583b00e3 Added function to retreive earnings calendar 2022-06-11 22:23:15 -04:00
rickturner01
d0606cdb03 Added get_earnings_history to fetch earnings data 2022-06-11 02:50:42 -04:00
andKraev
76a9b09e8e rename incorrect yahoo key treasuryStock 2022-05-27 16:53:17 +03:00
giorgossideris
d757b8f25f Handle case that the API returns no data for shares of a specific year 2022-05-09 15:24:10 +03:00
Kartheyan
ab50edf24c Fixed max period when interval is 1 minute
When attempting to retrieve the maximum period of time (period="max") at 1 minute intervals, the previous default start period of 1900-01-01 (631159200) would result in an error from the API with description "1m data not available for startTime=1497744000 and endTime=*NOW*. Only 7 days worth of 1m granularity data are allowed to be fetched per request." . By setting the start time to subtracting end time minus 604800 (86400*7), it now returns 1 week of 1 minute interval data which is the maximum period for which the API supports at 1 minute intervals.
2022-02-15 15:27:37 +00:00
alker0
9b4bce7d06 Support cache in Tickers() 2022-02-09 14:51:11 +09:00
Ran Aroussi
a396d93601 Update CHANGELOG.rst 2022-01-30 12:13:53 +00:00
Ran Aroussi
79d6741f1e Update version.py 2022-01-30 12:13:15 +00:00
Ran Aroussi
47a119f63b Update setup.py 2022-01-27 16:35:53 +00:00
Ran Aroussi
436c077ee2 Update requirements.txt 2022-01-27 16:35:43 +00:00
Ran Aroussi
72b1e9699e Merge pull request #941 from moshfrid/main
Explicitly set datetime index on actions table
2022-01-27 16:34:50 +00:00
Ran Aroussi
d2c2690cc2 Merge pull request #943 from rafaelsdellama/main
Fix: dev: AttributeError
2022-01-27 16:33:13 +00:00
Rafael Del Lama
65c1753fb2 lock pandas version on setup.py 2022-01-27 13:18:09 -03:00
Rafael Del Lama
93edc3c163 Fix: dev: AttributeError
Lock pandas version to fix AttributeError: 'Index' object has no attribute 'tz_localize' after pandas upgrade version to 1.4.0
2022-01-27 12:03:26 -03:00
moshfrid
b2e2acad06 Explicitly set datetime index on actions table
Explicitly set datetime index on actions df so that if the actions df is empty, it doesn't reset the index when combined with the rest of the dataframe.
2022-01-24 19:14:12 -05:00
ran
24e348e0e4 merged pr #920 2022-01-12 15:43:10 +00:00
Ran Aroussi
0ac69cfd49 Merge pull request #920 from tsherknus/main
Resolves UnboundLocalError in base.py history()
2022-01-12 15:41:34 +00:00
tsherknus
cdced94a00 Resolves UnboundLocalError in base.py history()
In base.py history(), session.get can return None or 404. Clarify exception catching within the history() method of base.py.

Ensure none and 404 values are caught prior to quote processing.

This prevents json parse exception, connection exception, or unbound exception from being thrown during data collection.

Includes updated unit testing.
2022-01-11 18:51:12 -05:00
ran
317239ec6c removed python 3.5 support 2021-12-30 15:36:11 +00:00
ran
6904fa9875 removed python 3.5 support 2021-12-30 15:35:43 +00:00
ran
2259a7a922 updated requests version solves some errors 2021-12-30 15:27:46 +00:00
Ran Aroussi
6ef4be3662 Merge pull request #896 from giorgossideris/shares_outstanding_addition
Make Historical Shares Outstanding number available (#892)
2021-12-30 15:26:48 +00:00
Ran Aroussi
44d2a5e001 Merge pull request #907 from tsherknus/yfinance_001
JSONDecodeError When Data is None
2021-12-30 15:26:38 +00:00
Ran Aroussi
0b88d2f552 Merge pull request #911 from asafravid/patch-12
Complementary key-statistics (currently fetching the important traili…
2021-12-30 15:25:30 +00:00
tsherknus
92a1470b86 Resolves an issue in base.py during historic retrieval of data.
In base.py history(), session.get can return None. Add an additional condition on line 190 of base.py has been added, which will throw a RuntimeError before the json parse exception can be thrown.
2021-12-30 08:40:54 -05:00
Asaf
4439d34d05 Complementary key-statistics (currently fetching the important trailingPegRatio which is the value shown in the website)
Complementary key-statistics (currently fetching the important trailingPegRatio which is the value shown in the website)
2021-12-20 14:21:31 +02:00
giorgossideris
063495a270 Make Historical Shares Outstanding number available (#892)
Before this commit there was no option to get the last 4 years' Shares Outstanding of a company. Now, this numbers can be found at the <code>Ticker.shares</code> attribute. Specifically, they refer to the average number of basic shares for each year.
2021-11-24 23:03:04 +02:00
Ran Aroussi
1297cd10e8 Merge pull request #891 from oliverlewis/oliverlewis/bug_Timezone_value_passed_on_to_the_option_chain_throws_TypeError 2021-11-21 10:41:35 +00:00
Oliver Lewis
9659af19ef typo changed to tz_convert 2021-11-20 23:23:56 -08:00
Oliver Lewis
16d7b54f4a passing utc true as default and adding dt field as series 2021-11-20 22:54:27 -08:00
Ran Aroussi
9040571ddd Update README.md 2021-11-20 20:50:16 +00:00
Ran Aroussi
4abad90a59 Delete docs directory 2021-11-20 20:21:56 +00:00
Ran Aroussi
0e52e92d4c Set theme jekyll-theme-minimal 2021-11-20 20:21:31 +00:00
ran
9eef951acc Added legal disclaimers
Added legal disclaimers to the README file to make sure people are aware that this library is not affiliated, endorsed, or vetted by Yahoo, Inc
2021-11-20 20:13:48 +00:00
Ran Aroussi
bc0cc1b42f Update and rename README.rst to README.md 2021-11-20 20:01:04 +00:00
Ran Aroussi
608849efc9 Update version.py 2021-11-13 22:53:47 +00:00
Ran Aroussi
1c390a51c2 Update CHANGELOG.rst 2021-11-13 22:53:36 +00:00
Ran Aroussi
cade9b0715 Merge pull request #885 from ShayAgros/main
Allow yfinance to be serialized by Pickle
2021-11-13 22:50:50 +00:00
Shay Agroskin
a1852184c4 Allow yfinance to be serialized by Pickle
Holding a reference to an object (Requests in this case) as part of the
object's attributes prevents it from being serialized by Pickle.

This commit removes such module reference as part of yfinance
attributes.

Signed-off-by: Shay Agroskin <shayagr@amazon.com>
2021-11-13 21:13:41 +02:00
Ran Aroussi
45be120cef Update README.rst 2021-11-13 17:35:55 +00:00
Ran Aroussi
c92b7ee3bf Update README.rst 2021-11-13 17:29:14 +00:00
ran
275c0fe002 more isin stuff (see changelog) 2021-11-13 17:25:23 +00:00
ran
4f27b17073 added lookup by isin
get_all_by_isin()
get_ticker_by_isin()
get_info_by_isin()
get_news_by_isin()
2021-11-13 16:51:11 +00:00
Ran Aroussi
a41b1820ac Merge pull request #883 from MatthiasSchinzel/timeout
Adding possibilty to modify timeout parameter of requests.get function.
2021-11-13 16:49:08 +00:00
Ran Aroussi
b1fc53134b Merge pull request #880 from AjitisAjit/main
Adds to analysis property that pulls content from analysis tab
2021-11-13 16:48:56 +00:00
Ran Aroussi
f83a63bd4e Merge pull request #857 from asafravid/main
try + except still required - topHoldings, summaryDetail
2021-11-13 16:48:33 +00:00
Matthias Schinzel
a76e12aca2 Fixing typo 2021-11-12 22:48:19 +01:00
Matthias Schinzel
43d037dd25 Propagating timeout parameter through code, setting request.get(timeout) 2021-11-12 22:39:24 +01:00
Ajit
bb202aa7a0 Adds Analysis 2021-11-10 20:04:58 +08:00
Ajit
15310a814a Fixes styling 2021-11-10 14:44:47 +08:00
Asaf
454b0dd885 try + except still required - topHoldings, summaryDetail
Reason is that a failure would be harmful without a graceful try+except
2021-10-21 18:47:53 +03:00
ran
6654a41a8d v# + clog 2021-10-19 21:29:06 +01:00
ran
25efeacab0 Merge branch 'main' of github.com:ranaroussi/yfinance 2021-10-19 21:25:40 +01:00
ran
0edce6b15c max = 1950 2021-10-19 21:25:37 +01:00
Ran Aroussi
4b9851562c Merge pull request #794 from jasonstrimpel/replace-drop-duplicate-prices-with-indexes
Replace drop duplicate prices with indexes
2021-10-19 21:24:43 +01:00
Ran Aroussi
016a724cb0 Merge pull request #786 from neon-paradise/feature/pre-market-price
add pre-market price to info
2021-10-19 21:21:31 +01:00
Ran Aroussi
4607ca69be Merge pull request #828 from asafravid/patch-8
When topHoldings is available (for ETFs) - provide it in the info. Closes #827
2021-10-19 21:21:01 +01:00
Ran Aroussi
969cd4bdf8 Merge branch 'main' into patch-8 2021-10-19 21:20:39 +01:00
Ran Aroussi
4a7dfb070b Merge pull request #855 from a0rtega/symbol_news
Add .news ticker property
2021-10-19 21:17:17 +01:00
ran
8568e4894b added stats() 2021-10-19 21:16:20 +01:00
Alberto Ortega
b42d176851 Add .news ticker property 2021-10-16 16:47:43 +02:00
Victor Silva
d0224ba940 Merge pull request #830 from asafravid/patch-9
For ETFs, provide this valuable data: the top holdings of the ETF. Closes #827
2021-10-13 12:16:23 -03:00
Victor Silva
e7bba3b7ff Merge pull request #815 from KilianB/patch-1
Do not use relative links in README
2021-10-13 12:06:45 -03:00
Asaf
7b37374bd0 or ETFs, provide this valuable data: the top holdings of the ETF
or ETFs, provide this valuable data: the top holdings of the ETF
2021-09-02 21:02:06 +03:00
Asaf
1f5a093c5a When topHoldings is available (for ETFs) - provide it in the info
For ETFs, provide this valuable data: the top holdings of the ETF 
       `if 'topHoldings' in data: self._info.update(data['topHoldings'])`
2021-08-31 23:56:29 +03:00
Kilian Brachtendorf
44f7bf6916 Do not use relative links in README
Relative links will not work when the README is displayed on an external page e.g. https://pypi.org/project/yfinance/ which is the first google entry for this project.
2021-08-16 13:19:47 +02:00
Jason Strimpel
b0a14b5498 Replace drop duplicate prices with indexes
Reindex the resutling price DataFrame by removing duplicate DatetimeIndex values instead of price data. Remove the call to groupby which is made redundant by the reindexing. This method appears to be the fastest based on a single data point found here.

This fixes an issue where valid trading days are removed from the returned data. Currently duplicates are dropped broadly under the (presumed) assumption that the chance of a stock's open, high, low, close and adjusted close all to be the same within a data range is an edge case that would never happen. With mutual funds and other securities that price daily (and correspondingly don't have a OHLC) this is much more likely.

Resolves: #793
2021-07-23 09:29:03 +08:00
pchernov
41be0a00a5 add pre-market price to info 2021-07-19 16:28:19 +03:00
Ran Aroussi
fc0f97926e Create bug_report.md 2021-07-10 21:55:48 +01:00
Ran Aroussi
7a3267ea3d Create bug_report.md 2021-07-10 21:54:59 +01:00
Ran Aroussi
920680bbe5 Update bug_report.md 2021-07-10 21:54:35 +01:00
Ran Aroussi
5733a1d9dd Update issue templates 2021-07-10 21:52:47 +01:00
Ran Aroussi
9a54340de3 Update README.rst 2021-07-10 21:33:21 +01:00
ran
6761b57f8b v# + changelog 2021-07-10 21:25:37 +01:00
ran
5ddb7f0406 duplicates and missing rows cleanup 2021-07-10 21:25:30 +01:00
ran
2bf3889106 added utils.user_agent_headers 2021-07-09 19:15:57 +01:00
ran
97e15d0f88 v# + changelog 2021-07-09 19:10:59 +01:00
ran
8a5c4acabd Added UserAgent to all requests 2021-07-09 19:10:53 +01:00
ran
1cc8d969f9 v# + changelog 2021-07-08 09:25:29 +01:00
ran
7a7995eb39 Switched to using query2.finance.yahoo.com, which used HTTP/1.1 2021-07-08 09:25:18 +01:00
ran
6df6a0402d ci stuff (2) 2021-07-03 14:42:50 +01:00
ran
73c8cea20e CI stuff 2021-07-03 14:41:02 +01:00
ran
7c4dbae2a7 ver + changelog 2021-07-03 14:25:50 +01:00
ran
7bd488ad74 graceful optionChain fail 2021-07-03 14:25:17 +01:00
ran
99e0b21031 introduced get_html for info() 2021-07-03 14:25:03 +01:00
ran
56d62676e4 pep stuff 2021-07-03 14:24:45 +01:00
ran
8b1f586a34 all tests are in test.py 2021-07-03 14:24:19 +01:00
ran
80b35b93a3 auto/back adjust graceful fail 2021-07-03 13:33:17 +01:00
ran
de5be0a9f4 added financialData 2021-07-03 13:23:04 +01:00
Ran Aroussi
11b8da4dad Merge pull request #721 from arnaudgelas/tests
Create a folder named 'tests' which contain all tests
2021-07-03 13:22:29 +01:00
Ran Aroussi
107cf9efac Merge pull request #730 from major/patch-1
✏ Trivial spelling fix
2021-07-03 13:19:10 +01:00
Ran Aroussi
f39cd175bf Merge pull request #734 from hughdavenport/hughdavenport-patch-1
Get price even if open price not available
2021-07-03 13:18:50 +01:00
Ran Aroussi
f5df1d5544 Merge pull request #743 from asafravid/master
self._history() graceful handling in case it fails
2021-07-03 13:17:41 +01:00
Ran Aroussi
a10714d1ac Merge branch 'main' into master 2021-07-03 13:17:35 +01:00
Ran Aroussi
2d480e0c67 Merge pull request #749 from jonathanng/main
added header
2021-07-03 13:15:34 +01:00
Jonathan Ng
e80bea1cfc added header 2021-07-02 09:26:20 -04:00
Asaf
2aa163828a Add headers to session
Add headers to session
2021-07-02 08:10:06 +03:00
Arnaud Gelas
3709d88343 Create a folder named 'tests' which contain all tests 2021-07-01 20:41:28 +02:00
Asaf
dcf3e25ed8 Remove unecessary else after return
Remove unecessary else after return
2021-06-28 12:30:55 +03:00
Asaf
c8bbc725e3 Add checks after self._history() in get_() functions
- get_dividends(), get_splits() and get_actions():
  - Since self.history(() may fail, if self._history is not None needs to be re-checked (As well as the action within self._history
2021-06-28 12:24:41 +03:00
Asaf
027beac6d2 Delete base.py 2021-06-28 12:23:53 +03:00
Asaf
5dda3c4f3f Add None checks after self.history() which may fail
- get_dividends(), get_splits() and get_actions():
  - Since self.history(() may fail, if self._history is not None needs to be re-checked (As well as the action within self._history
2021-06-28 12:22:52 +03:00
Hugh Davenport
3288aabe7a If summaryDetail fails, pull in the price dict
For some tickers, such as `ETHI.AX`, the `summaryDetail` result is `None`. In this case, use the `price` dict if possible.
2021-06-16 13:07:09 +12:00
Hugh Davenport
bfe2befb2b Get price even if open price not available
If for some reason the regularMarketOpen value is not retrieved in the summaryDetail, then still attempt to retrieve the regularMarketPrice
2021-06-16 12:42:24 +12:00
Major Hayden
a4f8a9d3dd ✏ Trivial spelling fix 2021-06-08 07:47:25 -05:00
silvavn
76b346765f added requirements to ci 2021-06-05 16:24:49 -06:00
silvavn
f5ce434865 quickfix 2021-06-05 16:20:06 -06:00
Victor Silva
9a9e21ab03 Merge pull request #728 from ranaroussi/documentation
Documentation
2021-06-05 16:15:57 -06:00
silvavn
419b897ed6 Deploy website 2021-06-05 16:14:09 -06:00
silvavn
4e3943d2f2 Mkdocs documentation 2021-05-29 17:22:07 -06:00
Victor Silva
ee92950242 Merge pull request #698 from ranaroussi/dependabot/add-v2-config-file
Upgrade to GitHub-native Dependabot
2021-05-29 16:16:22 -06:00
Victor Silva
3f28b11937 Merge pull request #717 from pranjal-joshi/main
[New Feature] Argument added for silencing error printing
2021-05-25 14:40:26 -06:00
Pranjal Joshi
b8bade44b8 Argument added for silencing error printing
`show_errors` argument added to `download` function with default value `True`.
`if show_errors == False` then errors will not be printed.
This is a fix for **Symbol Delisted** error printed if the data for that symbol is unavailable on Yahoo! finance.
2021-05-21 13:38:27 +05:30
dependabot-preview[bot]
a08823febe Upgrade to GitHub-native Dependabot 2021-04-29 20:25:09 +00:00
ran
eb42fbfbcd version bump + changelog update 2021-03-25 00:42:57 +00:00
ran
ad11f61ef5 added session to holders 2021-03-25 00:42:41 +00:00
ran
ca1377305f changelog update + version bump 2021-03-25 00:05:04 +00:00
ran
824b3d47d1 Allow specifying a custom requests session instance 2021-03-25 00:04:41 +00:00
ran
d4dafa4850 updated changelog 2021-03-24 23:36:48 +00:00
ran
fac8304454 fixed issue with special characters in tickers 2021-03-24 23:36:32 +00:00
ran
1d68e56fba Fixed issue with 1 hour interval 2021-03-24 23:26:16 +00:00
ran
ab8eef710c conda meta file 2021-03-24 23:26:16 +00:00
ran
959afa3213 moved version to external file 2021-03-24 23:26:16 +00:00
Ran Aroussi
3248fed613 Merge pull request #410 from trenton3983/master
Add link to SO question on how to deal with multi-level dataframe column name
2021-03-24 23:25:37 +00:00
Ran Aroussi
e77a1cf293 Merge pull request #635 from jlsajfj/master
Fix for issue of 1 hour interval incorrect date
2021-03-24 23:16:33 +00:00
Ran Aroussi
51ead25faa Merge pull request #643 from asafravid/sync-with-ranaroussi/yfinance-v0.1.56
2 important updates
2021-03-24 23:09:36 +00:00
Asaf
65b0e343d7 Merge branch 'main' into sync-with-ranaroussi/yfinance-v0.1.56 2021-03-25 00:15:09 +02:00
Asaf
a82ff40423 2 updates
1. Add trys and catch where misssing
2. Add "financialCurrency" property to earnings so as to allow required conversion rate for USD comparisons with USD-based fields
2021-03-24 23:51:29 +02:00
ran
81d3ea5e95 PR merged 2021-03-24 11:34:23 +00:00
Ran Aroussi
b12b1eceff Update README.rst 2021-03-24 11:24:16 +00:00
Ran Aroussi
9a2a21a7ef Update README.rst 2021-03-24 11:22:27 +00:00
Ran Aroussi
8b6960f966 Update setup.py 2021-03-24 11:21:03 +00:00
Ran Aroussi
1d247c7a4a Update .travis.yml 2021-03-24 11:20:39 +00:00
jlsajfj
d912d1380a Fix for issue of 1 hour interval incorrect date
Fix was found [here](https://stackoverflow.com/a/65260400)
2021-03-18 10:25:43 -04:00
Victor Silva
8bdc51f9fa Merge pull request #506 from HMellor/master
LGTM. Testing is now done with PyTest.
2021-03-14 09:39:57 -06:00
Victor Silva
cf8ed4d3f3 Merge pull request #217 from ceppelli/master
Merging as this was a missing piece of code.
2021-03-14 09:25:31 -06:00
Victor Silva
c0849956ae Merge pull request #169 from mapogu/ticket_xyz_financial_data
Merged as this was a missing piece of information.
2021-03-14 09:23:04 -06:00
Victor Silva
a3201984e9 Merge pull request #157 from zhenwenc/fix-missing-proxy-param
Merged as this was definitely a missing piece of code.
2021-03-14 09:18:33 -06:00
Asaf
20a869a204 Revert to 'USD' when there is no 'financialCurrency' does not exist
Revert to 'USD' when there is no 'financialCurrency' does not exist
2021-03-10 02:53:29 +02:00
Asaf
16536bf18e Add 'financialCurrency' to earnings
Add 'financialCurrency' to earnings
It is a MUST for comparing earnings and/or revenues, to the marketCap and enterpriseValue
2021-03-09 21:55:28 +02:00
Ran Aroussi
b9a0e64284 Create a release → publish to PyPi
Publishes a new version on PyPi whenever a new release version is created on Github
2021-03-03 23:34:48 +00:00
Victor Silva
649f15bdca Merge pull request #507 from danieljllo/master
Fix README.rst 'compatibility' typo
2021-03-02 12:44:36 -07:00
beglitis
a72557bddc Merge pull request #480 from PaulRenvoise/fix/fundamentals
Fix the fetching of fundamentals
2021-01-18 14:16:47 +00:00
beglitis
58b3eaf23f Merge pull request #529 from ussfletcher/patch-1
Update base.py
2021-01-11 09:52:24 +00:00
ussfletcher
ad5ca232af Update base.py
Proxy was not successfully passed through in calls to _get_fundamentals. This is due to _get_fundamentals having two keyword arguments "def _get_fundamentals(self, kind=None, proxy=None):" thus proxy was being stored to "kind" by default.

Fixed by adding keyword back into calls to _get_fundamentals
2020-12-09 17:47:23 -08:00
danieljllo
b58b809412 Fix README.rst 'compatibility' typo 2020-11-21 09:39:00 -06:00
HMellor
54191ca10c Swap badge from my username to yours 2020-11-21 11:21:24 +00:00
HMellor
80525860e2 Add minimum pytest version install 2020-11-21 10:59:59 +00:00
HMellor
3dde9d6e8c Add automatic testing and coverage 2020-11-21 10:38:06 +00:00
Asaf
79b33bbb4d Fix Holders error for no tables found
This Pull request must be pulled in it is a major fix
2020-11-11 23:30:03 +02:00
Paul Renvoisé
e28283a964 fix(get_fundamentals) prevent the override of ticker url by holders url 2020-10-19 14:21:10 +02:00
Trenton J. McKinney
46b0ab7787 Update README.rst 2020-08-05 14:00:04 -07:00
Trenton J. McKinney
3898215ed6 Update README.rst 2020-08-05 13:57:51 -07:00
Trenton J. McKinney
e79256891f Update README.rst 2020-08-05 13:57:00 -07:00
Trenton J. McKinney
d65063d316 Update README.rst 2020-08-05 13:55:24 -07:00
Trenton J. McKinney
15c8b9aea7 Update README.rst 2020-08-05 13:52:18 -07:00
Trenton J. McKinney
a4fa6b5abe Update README.rst
I've added this update as per https://twitter.com/Aroussi/status/1291009917818736641 with Ran Aroussi. This update adds a link to a stack overflow answer, which discusses dealing with multi-level column names.
2020-08-05 13:46:24 -07:00
ceppelli
a62f9cc1ea [FIX] - proxy parameter is not propagated correcty in the _get_fundamentals method 2020-03-10 16:21:49 +01:00
mapogu
ae5aad9c67 Add financialData to info 2020-01-14 13:25:36 +01:00
Frederick Cai
40f3a1ee7f added missing proxy parameter 2020-01-01 18:21:08 +13:00
23 changed files with 1834 additions and 620 deletions

20
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,20 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
*** READ BEFORE POSTING ***
Before posting an issue - please upgrade to the latest version and confirm the issue/bug is still there.
Upgrade using:
`$ pip install yfinance --upgrade --no-cache-dir`
Bug still there? Delete this content and submit your bug report here and provide the following, as best you can:
- Simple code that reproduces your problem
- The error message

7
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
version: 2
updates:
- package-ecosystem: pip
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10

18
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
name: ci
on:
push:
branches:
- master
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
with:
python-version: 3.x
- run: pip install -r requirements.txt
- run: pip install mkdocstrings==0.14.0
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force

31
.github/workflows/python-publish.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
name: Upload Python Package
on:
release:
types: [created]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*

6
.gitignore vendored
View File

@@ -3,3 +3,9 @@ yfinance/__pycache__/*
dist
yfinance.egg-info
*.pyc
.coverage
.vscode/
build/
*.html
*.css
*.png

View File

@@ -6,26 +6,30 @@ fast_finish: true
matrix:
include:
- python: 2.7
- python: 3.5
- python: 3.6
- python: 3.7
- python: 3.8
- python: 3.9
dist: xenial
sudo: true
install:
- pip install Cython
- pip install pytest>=4.6
- pip install pytest-cov
- pip install coveralls
- pip install -r requirements.txt
- pip install .
script:
- nosetests
- pytest --cov=yfinance/
after_success:
- coveralls
branches:
only:
- master
- main
notifications:
slack: tradologics:HcnS6XusfcuS02waQPCG18oc

View File

@@ -1,10 +1,196 @@
Change Log
===========
0.1.55 - to be released
0.1.96
------
- fixed institutional investors and mutual fund holders issue (#459)
- fix for UTC timestamps in options chains (#429)
- Fix info[] not caching #1258
0.1.95
------
- Fix info[] bug #1257
0.1.94
------
- Fix delisted ticker info[]
0.1.93
------
- Fix Ticker.shares
0.1.92
------
- Decrypt new Yahoo encryption #1255
0.1.90
------
- Restore lxml req, increase min ver #1237
0.1.89
------
- Remove unused incompatible dependency #1222
- Fix minimum Pandas version #1230
0.1.87
------
- Fix localizing midnight when non-existent (DST) #1176
- Fix thread deadlock in bpython #1163
0.1.86
------
- Fix 'trailingPegRatio' #1141
- Improve handling delisted tickers #1142
- Fix corrupt tkr-tz-csv halting code #1162
- Change default start to 1900-01-01 #1170
0.1.85
------
- Fix info['log_url'] #1062
- Fix handling delisted ticker #1137
0.1.84
------
- Make tz-cache thread-safe
0.1.83
------
- Reduce spam-effect of tz-fetch
0.1.81
------
- Fix unhandled tz-cache exception #1107
0.1.80
------
- Fix `download(ignore_tz=True)` for single ticker #1097
- Fix rare case of error "Cannot infer DST time" #1100
0.1.79
------
- Fix when Yahoo returns price=NaNs on dividend day
0.1.78
------
- Fix download() when different timezones #1085
0.1.77
------
- Fix user experience bug #1078
0.1.75
------
- Fixed datetime-related issues: #1048
- Add 'keepna' argument #1032
- Speedup Ticker() creation #1042
- Improve a bugfix #1033
0.1.74
------
- Fixed bug introduced in 0.1.73 (sorry :/)
0.1.73
------
- Merged several PR that fixed misc issues
0.1.72
------
- Misc bugfixs
0.1.71
------
- Added Tickers(…).news()
- Return empty DF if YF missing earnings dates
- Fix EPS % to 0->1
- Fix timezone handling
- Fix handling of missing data
- Clean&format earnings_dates table
- Add ``.get_earnings_dates()`` to retreive earnings calendar
- Added ``.get_earnings_history()`` to fetch earnings data
0.1.70
------
- Bug fixed - Closes #937
0.1.69
------
- Bug fixed - #920
0.1.68
------
- Upgraded requests dependency
- Removed Python 3.5 support
0.1.67
------
- Added legal disclaimers to make sure people are aware that this library is not affiliated, endorsed, or vetted by Yahoo, Inc.
0.1.66
------
- Merged PR to allow yfinance to be pickled
0.1.65
------
- Merged PRs to fix some bugs
- Added lookup by ISIN ``utils.get_all_by_isin(...)``, ``utils.get_ticker_by_isin(...)``, ``utils.get_info_by_isin(...)``, ``utils.get_news_by_isin(...)``
- ``yf.Ticker``, ``yf.Tickers``, and ``yf.download`` will auto-detect ISINs and convert them to tickers
- Propagating timeout parameter through code, setting request.get(timeout)
- Adds ``Ticker.analysis`` and ``Ticker.get_analysis(...)``
0.1.64
------
- Merged PRs to fix some bugs
- Added ``Ticker.stats()`` method
- Added ``Ticker.news`` property
- Providing topHoldings for ETFs
- Replaceed drop duplicate prices with indexes
- Added pre-market price to ``Ticker.info``
0.1.63
------
- Duplicates and missing rows cleanup
0.1.62
------
- Added UserAgent to all requests (via ```utils.user_agent_headers```)
0.1.61
------
- Switched to using ```query2.finance.yahoo.com```, which used HTTP/1.1
0.1.60
------
- Gracefully fail on misc operations (options, auto/back adjustments, etc)
- Added financial data to ```info()```
- Using session headers
- Get price even if open price not available
- Argument added for silencing error printing
- Merged PRs to fix some bugs
0.1.59
------
- Added custom requests session instance support in holders
0.1.58
------
- Allow specifying a custom requests session instance
0.1.57
------
- Added Conversion rate hint using 'financialCurrency' property in earnings
- Add important try+catch statements
- Fixed issue with 1 hour interval
- Merged PRs to fix some bugs
- Fixed issue with special characters in tickers
0.1.56
------
- Updated numpy version
- Merged PRs to fix some bugs
0.1.55
------
- Fixed institutional investors and mutual fund holders issue (#459)
- Fix for UTC timestamps in options chains (#429)
0.1.54
------
@@ -12,7 +198,7 @@ Change Log
0.1.53
------
- Added `Ticker.isin` + `Ticker.get_isin(...)`. This is still experimental. Do not rely on it for production.
- Added ``Ticker.isin`` + ``Ticker.get_isin(...)``. This is still experimental. Do not rely on it for production.
- Bug fixed: holders were always returning results for MSFT
0.1.52
@@ -21,24 +207,24 @@ Change Log
0.1.51
------
- Added holdings data (`Ticker.major_holders` and `Ticker.institutional_holders`)
- Added logo url to `Ticker.info`
- Added holdings data (``Ticker.major_holders`` and ``Ticker.institutional_holders``)
- Added logo url to ``Ticker.info``
- Handling different date formats in fundamentals
- Faster JSON parsing using regex
- Trying to re-download JSON twice before giving up
- Using ujson instead of json if installed
- Fixed (more) `ticker.info` issues
- Fixed (more) ``ticker.info`` issues
- Misc bugfixes
0.1.50
------
- Fixed `ticker.info` issues
- Fixed ``ticker.info`` issues
- Handle sustainability index error
- Added test script based on @GregoryMorse's pull request
0.1.49
------
- Fixed `elementwise comparison`` warning
- Fixed ``elementwise comparison`` warning
0.1.48
------

311
README.md Normal file
View File

@@ -0,0 +1,311 @@
# Download market data from Yahoo! Finance's API
<table border=1 cellpadding=10><tr><td>
#### \*\*\* IMPORTANT LEGAL DISCLAIMER \*\*\*
---
**Yahoo!, Y!Finance, and Yahoo! finance are registered trademarks of
Yahoo, Inc.**
yfinance is **not** affiliated, endorsed, or vetted by Yahoo, Inc. It's
an open-source tool that uses Yahoo's publicly available APIs, and is
intended for research and educational purposes.
**You should refer to Yahoo!'s terms of use**
([here](https://policies.yahoo.com/us/en/yahoo/terms/product-atos/apiforydn/index.htm),
[here](https://legal.yahoo.com/us/en/yahoo/terms/otos/index.html), and
[here](https://policies.yahoo.com/us/en/yahoo/terms/index.htm)) **for
details on your rights to use the actual data downloaded. Remember - the
Yahoo! finance API is intended for personal use only.**
</td></tr></table>
---
<a target="new" href="https://pypi.python.org/pypi/yfinance"><img border=0 src="https://img.shields.io/badge/python-2.7,%203.6+-blue.svg?style=flat" alt="Python version"></a>
<a target="new" href="https://pypi.python.org/pypi/yfinance"><img border=0 src="https://img.shields.io/pypi/v/yfinance.svg?maxAge=60%" alt="PyPi version"></a>
<a target="new" href="https://pypi.python.org/pypi/yfinance"><img border=0 src="https://img.shields.io/pypi/status/yfinance.svg?maxAge=60" alt="PyPi status"></a>
<a target="new" href="https://pypi.python.org/pypi/yfinance"><img border=0 src="https://img.shields.io/pypi/dm/yfinance.svg?maxAge=2592000&label=installs&color=%2327B1FF" alt="PyPi downloads"></a>
<a target="new" href="https://travis-ci.com/github/ranaroussi/yfinance"><img border=0 src="https://img.shields.io/travis/ranaroussi/yfinance/main.svg?maxAge=1" alt="Travis-CI build status"></a>
<a target="new" href="https://www.codefactor.io/repository/github/ranaroussi/yfinance"><img border=0 src="https://www.codefactor.io/repository/github/ranaroussi/yfinance/badge" alt="CodeFactor"></a>
<a target="new" href="https://github.com/ranaroussi/yfinance"><img border=0 src="https://img.shields.io/github/stars/ranaroussi/yfinance.svg?style=social&label=Star&maxAge=60" alt="Star this repo"></a>
<a target="new" href="https://twitter.com/aroussi"><img border=0 src="https://img.shields.io/twitter/follow/aroussi.svg?style=social&label=Follow&maxAge=60" alt="Follow me on twitter"></a>
**yfinance** offers a threaded and Pythonic way to download market data from [Yahoo!Ⓡ finance](https://finance.yahoo.com).
→ Check out this [Blog post](https://aroussi.com/#post/python-yahoo-finance) for a detailed tutorial with code examples.
[Changelog »](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst)
---
## Quick Start
### The Ticker module
The `Ticker` module, which allows you to access ticker data in a more Pythonic way:
```python
import yfinance as yf
msft = yf.Ticker("MSFT")
# get stock info
msft.info
# get historical market data
hist = msft.history(period="max")
# show actions (dividends, splits)
msft.actions
# show dividends
msft.dividends
# show splits
msft.splits
# show financials
msft.financials
msft.quarterly_financials
# show major holders
msft.major_holders
# show institutional holders
msft.institutional_holders
# show balance sheet
msft.balance_sheet
msft.quarterly_balance_sheet
# show cashflow
msft.cashflow
msft.quarterly_cashflow
# show earnings
msft.earnings
msft.quarterly_earnings
# show sustainability
msft.sustainability
# show analysts recommendations
msft.recommendations
# show next event (earnings, etc)
msft.calendar
# show all earnings dates
msft.earnings_dates
# show ISIN code - *experimental*
# ISIN = International Securities Identification Number
msft.isin
# show options expirations
msft.options
# show news
msft.news
# get option chain for specific expiration
opt = msft.option_chain('YYYY-MM-DD')
# data available via: opt.calls, opt.puts
```
If you want to use a proxy server for downloading data, use:
```python
import yfinance as yf
msft = yf.Ticker("MSFT")
msft.history(..., proxy="PROXY_SERVER")
msft.get_actions(proxy="PROXY_SERVER")
msft.get_dividends(proxy="PROXY_SERVER")
msft.get_splits(proxy="PROXY_SERVER")
msft.get_balance_sheet(proxy="PROXY_SERVER")
msft.get_cashflow(proxy="PROXY_SERVER")
msft.option_chain(..., proxy="PROXY_SERVER")
...
```
To use a custom `requests` session (for example to cache calls to the
API or customize the `User-agent` header), pass a `session=` argument to
the Ticker constructor.
```python
import requests_cache
session = requests_cache.CachedSession('yfinance.cache')
session.headers['User-agent'] = 'my-program/1.0'
ticker = yf.Ticker('msft aapl goog', session=session)
# The scraped response will be stored in the cache
ticker.actions
```
To initialize multiple `Ticker` objects, use
```python
import yfinance as yf
tickers = yf.Tickers('msft aapl goog')
# ^ returns a named tuple of Ticker objects
# access each ticker using (example)
tickers.tickers.MSFT.info
tickers.tickers.AAPL.history(period="1mo")
tickers.tickers.GOOG.actions
```
### Fetching data for multiple tickers
```python
import yfinance as yf
data = yf.download("SPY AAPL", start="2017-01-01", end="2017-04-30")
```
I've also added some options to make life easier :)
```python
data = yf.download( # or pdr.get_data_yahoo(...
# tickers list or string as well
tickers = "SPY AAPL MSFT",
# use "period" instead of start/end
# valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
# (optional, default is '1mo')
period = "ytd",
# fetch data by interval (including intraday if period < 60 days)
# valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
# (optional, default is '1d')
interval = "1m",
# Whether to ignore timezone when aligning ticker data from
# different timezones. Default is True. False may be useful for
# minute/hourly data.
ignore_tz = False,
# group by ticker (to access via data['SPY'])
# (optional, default is 'column')
group_by = 'ticker',
# adjust all OHLC automatically
# (optional, default is False)
auto_adjust = True,
# download pre/post regular market hours data
# (optional, default is False)
prepost = True,
# use threads for mass downloading? (True/False/Integer)
# (optional, default is True)
threads = True,
# proxy URL scheme use use when downloading?
# (optional, default is None)
proxy = None
)
```
### Timezone cache store
When fetching price data, all dates are localized to stock exchange timezone.
But timezone retrieval is relatively slow, so yfinance attemps to cache them
in your users cache folder.
You can direct cache to use a different location with `set_tz_cache_location()`:
```python
import yfinance as yf
yf.set_tz_cache_location("custom/cache/location")
...
```
### Managing Multi-Level Columns
The following answer on Stack Overflow is for [How to deal with
multi-level column names downloaded with
yfinance?](https://stackoverflow.com/questions/63107801)
- `yfinance` returns a `pandas.DataFrame` with multi-level column
names, with a level for the ticker and a level for the stock price
data
- The answer discusses:
- How to correctly read the the multi-level columns after
saving the dataframe to a csv with `pandas.DataFrame.to_csv`
- How to download single or multiple tickers into a single
dataframe with single level column names and a ticker column
---
## `pandas_datareader` override
If your code uses `pandas_datareader` and you want to download data
faster, you can "hijack" `pandas_datareader.data.get_data_yahoo()`
method to use **yfinance** while making sure the returned data is in the
same format as **pandas\_datareader**'s `get_data_yahoo()`.
```python
from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override() # <== that's all it takes :-)
# download dataframe
data = pdr.get_data_yahoo("SPY", start="2017-01-01", end="2017-04-30")
```
---
## Installation
Install `yfinance` using `pip`:
``` {.sourceCode .bash}
$ pip install yfinance --upgrade --no-cache-dir
```
To install `yfinance` using `conda`, see
[this](https://anaconda.org/ranaroussi/yfinance).
### Requirements
- [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
- [lxml](https://pypi.org/project/lxml/) \>= 4.9.1
- [appdirs](https://pypi.org/project/appdirs) \>= 1.4.4
- [cryptography](https://pypi.org/project/cryptography) \>=3.3.2
### Optional (if you want to use `pandas_datareader`)
- [pandas\_datareader](https://github.com/pydata/pandas-datareader)
\>= 0.4.0
---
### Legal Stuff
**yfinance** is distributed under the **Apache Software License**. See
the [LICENSE.txt](./LICENSE.txt) file in the release for details.
AGAIN - yfinance is **not** affiliated, endorsed, or vetted by Yahoo, Inc. It's
an open-source tool that uses Yahoo's publicly available APIs, and is
intended for research and educational purposes. You should refer to Yahoo!'s terms of use
([here](https://policies.yahoo.com/us/en/yahoo/terms/product-atos/apiforydn/index.htm),
[here](https://legal.yahoo.com/us/en/yahoo/terms/otos/index.html), and
[here](https://policies.yahoo.com/us/en/yahoo/terms/index.htm)) for
detailes on your rights to use the actual data downloaded.
---
### P.S.
Please drop me an note with any feedback you have.
**Ran Aroussi**

View File

@@ -1,277 +0,0 @@
Yahoo! Finance market data downloader
=====================================
.. image:: https://img.shields.io/badge/python-2.7,%203.4+-blue.svg?style=flat
:target: https://pypi.python.org/pypi/yfinance
:alt: Python version
.. image:: https://img.shields.io/pypi/v/yfinance.svg?maxAge=60
:target: https://pypi.python.org/pypi/yfinance
:alt: PyPi version
.. image:: https://img.shields.io/pypi/status/yfinance.svg?maxAge=60
:target: https://pypi.python.org/pypi/yfinance
:alt: PyPi status
.. image:: https://img.shields.io/pypi/dm/yfinance.svg?maxAge=2592000&label=installs&color=%2327B1FF
:target: https://pypi.python.org/pypi/yfinance
:alt: PyPi downloads
.. image:: https://img.shields.io/travis/ranaroussi/yfinance/master.svg?maxAge=1
:target: https://travis-ci.com/ranaroussi/yfinance
:alt: Travis-CI build status
.. image:: https://www.codefactor.io/repository/github/ranaroussi/yfinance/badge
:target: https://www.codefactor.io/repository/github/ranaroussi/yfinance
:alt: CodeFactor
.. image:: https://img.shields.io/github/stars/ranaroussi/yfinance.svg?style=social&label=Star&maxAge=60
:target: https://github.com/ranaroussi/yfinance
:alt: Star this repo
.. image:: https://img.shields.io/twitter/follow/aroussi.svg?style=social&label=Follow&maxAge=60
:target: https://twitter.com/aroussi
:alt: Follow me on twitter
\
Ever since `Yahoo! finance <https://finance.yahoo.com>`_ decommissioned
their historical data API, many programs that relied on it to stop working.
**yfinance** aimes to solve this problem by offering a reliable, threaded,
and Pythonic way to download historical market data from Yahoo! finance.
NOTE
~~~~
The library was originally named ``fix-yahoo-finance``, but
I've since renamed it to ``yfinance`` as I no longer consider it a mere "fix".
For reasons of backward-competability, ``fix-yahoo-finance`` now import and
uses ``yfinance``, but you should install and use ``yfinance`` directly.
`Changelog » <./CHANGELOG.rst>`__
-----
==> Check out this `Blog post <https://aroussi.com/#post/python-yahoo-finance>`_ for a detailed tutorial with code examples.
-----
Quick Start
===========
The Ticker module
~~~~~~~~~~~~~~~~~
The ``Ticker`` module, which allows you to access
ticker data in a more Pythonic way:
Note: yahoo finance datetimes are received as UTC.
.. code:: python
import yfinance as yf
msft = yf.Ticker("MSFT")
# get stock info
msft.info
# get historical market data
hist = msft.history(period="max")
# show actions (dividends, splits)
msft.actions
# show dividends
msft.dividends
# show splits
msft.splits
# show financials
msft.financials
msft.quarterly_financials
# show major holders
msft.major_holders
# show institutional holders
msft.institutional_holders
# show balance sheet
msft.balance_sheet
msft.quarterly_balance_sheet
# show cashflow
msft.cashflow
msft.quarterly_cashflow
# show earnings
msft.earnings
msft.quarterly_earnings
# show sustainability
msft.sustainability
# show analysts recommendations
msft.recommendations
# show next event (earnings, etc)
msft.calendar
# show ISIN code - *experimental*
# ISIN = International Securities Identification Number
msft.isin
# show options expirations
msft.options
# get option chain for specific expiration
opt = msft.option_chain('YYYY-MM-DD')
# data available via: opt.calls, opt.puts
If you want to use a proxy server for downloading data, use:
.. code:: python
import yfinance as yf
msft = yf.Ticker("MSFT")
msft.history(..., proxy="PROXY_SERVER")
msft.get_actions(proxy="PROXY_SERVER")
msft.get_dividends(proxy="PROXY_SERVER")
msft.get_splits(proxy="PROXY_SERVER")
msft.get_balance_sheet(proxy="PROXY_SERVER")
msft.get_cashflow(proxy="PROXY_SERVER")
msft.option_chain(..., proxy="PROXY_SERVER")
...
To initialize multiple ``Ticker`` objects, use
.. code:: python
import yfinance as yf
tickers = yf.Tickers('msft aapl goog')
# ^ returns a named tuple of Ticker objects
# access each ticker using (example)
tickers.tickers.MSFT.info
tickers.tickers.AAPL.history(period="1mo")
tickers.tickers.GOOG.actions
Fetching data for multiple tickers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python
import yfinance as yf
data = yf.download("SPY AAPL", start="2017-01-01", end="2017-04-30")
I've also added some options to make life easier :)
.. code:: python
data = yf.download( # or pdr.get_data_yahoo(...
# tickers list or string as well
tickers = "SPY AAPL MSFT",
# use "period" instead of start/end
# valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
# (optional, default is '1mo')
period = "ytd",
# fetch data by interval (including intraday if period < 60 days)
# valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
# (optional, default is '1d')
interval = "1m",
# group by ticker (to access via data['SPY'])
# (optional, default is 'column')
group_by = 'ticker',
# adjust all OHLC automatically
# (optional, default is False)
auto_adjust = True,
# download pre/post regular market hours data
# (optional, default is False)
prepost = True,
# use threads for mass downloading? (True/False/Integer)
# (optional, default is True)
threads = True,
# proxy URL scheme use use when downloading?
# (optional, default is None)
proxy = None
)
``pandas_datareader`` override
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If your code uses ``pandas_datareader`` and you want to download data faster,
you can "hijack" ``pandas_datareader.data.get_data_yahoo()`` method to use
**yfinance** while making sure the returned data is in the same format as
**pandas_datareader**'s ``get_data_yahoo()``.
.. code:: python
from pandas_datareader import data as pdr
import yfinance as yf
yf.pdr_override() # <== that's all it takes :-)
# download dataframe
data = pdr.get_data_yahoo("SPY", start="2017-01-01", end="2017-04-30")
Installation
------------
Install ``yfinance`` using ``pip``:
.. code:: bash
$ pip install yfinance --upgrade --no-cache-dir
Install ``yfinance`` using ``conda``:
.. code:: bash
$ conda install -c ranaroussi yfinance
Requirements
------------
* `Python <https://www.python.org>`_ >= 2.7, 3.4+
* `Pandas <https://github.com/pydata/pandas>`_ (tested to work with >=0.23.1)
* `Numpy <http://www.numpy.org>`_ >= 1.11.1
* `requests <http://docs.python-requests.org/en/master/>`_ >= 2.14.2
* `lxml <https://pypi.org/project/lxml/>`_ >= 4.5.1
Optional (if you want to use ``pandas_datareader``)
---------------------------------------------------
* `pandas_datareader <https://github.com/pydata/pandas-datareader>`_ >= 0.4.0
Legal Stuff
------------
**yfinance** is distributed under the **Apache Software License**. See the `LICENSE.txt <./LICENSE.txt>`_ file in the release for details.
P.S.
------------
Please drop me an note with any feedback you have.
**Ran Aroussi**

View File

@@ -1,5 +1,5 @@
{% set name = "yfinance" %}
{% set version = "0.1.55" %}
{% set version = "0.1.96" %}
package:
name: "{{ name|lower }}"
@@ -7,7 +7,7 @@ package:
source:
url: "https://pypi.io/packages/source/{{ name[0] }}/{{ name }}/{{ name }}-{{ version }}.tar.gz"
sha256: "89e984306bee13ed9a1a5d543f4f01f85716120666e404596a4e932ac7448288"
sha256: "207da19e87792bf742d2744eee2fe18169853c1b82cfe14a9a7cfb8d05f09137"
build:
noarch: python
@@ -16,20 +16,25 @@ build:
requirements:
host:
- pandas >=1.3.0
- numpy >=1.16.5
- requests >=2.26
- multitasking >=0.0.7
- numpy >=1.15
- pandas >=0.24
- lxml >=4.9.1
- appdirs >= 1.4.4
- cryptography >= 3.3.2
- pip
- python
- requests >=2.20
- lxml>=4.5.1
run:
- pandas >=1.3.0
- numpy >=1.16.5
- requests >=2.26
- multitasking >=0.0.7
- numpy >=1.15
- pandas >=0.24
- lxml >=4.9.1
- appdirs >= 1.4.4
- cryptography >= 3.3.2
- python
- requests >=2.20
- lxml>=4.5.1
test:
imports:
@@ -50,4 +55,3 @@ about:
extra:
recipe-maintainers:
- ranaroussi
- bradmetz

19
mkdocs.yml Normal file
View File

@@ -0,0 +1,19 @@
# site_name: My Docs
# # mkdocs.yml
# theme:
# name: "material"
# plugins:
# - search
# - mkdocstrings
# nav:
# - Introduction: 'index.md'
# - Installation: 'installation.md'
# - Quick Start: 'quickstart.md'
# # - Ticker: 'Ticker.md'
# - TickerBase: 'TickerBase.md'
# # - Tickers: 'Tickers.md'
# - utils: 'utils.md'
# - multi: 'multi.md'

View File

@@ -1,5 +1,7 @@
pandas>=0.24
numpy>=1.15
requests>=2.21
pandas>=1.3.0
numpy>=1.16.5
requests>=2.26
multitasking>=0.0.7
lxml>=4.5.1
lxml>=4.9.1
appdirs>=1.4.4
cryptography>=3.3.2

View File

@@ -1,64 +0,0 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# https://github.com/ranaroussi/yfinance
"""
Sanity check for most common library uses all working
- Stock: Microsoft
- ETF: Russell 2000 Growth
- Mutual fund: Vanguard 500 Index fund
- Index: S&P500
- Currency BTC-USD
"""
from __future__ import print_function
import yfinance as yf
def test_yfinance():
for symbol in ['MSFT', 'IWO', 'VFINX', '^GSPC', 'BTC-USD']:
print(">>", symbol, end=' ... ')
ticker = yf.Ticker(symbol)
# always should have info and history for valid symbols
assert(ticker.info is not None and ticker.info != {})
assert(ticker.history(period="max").empty is False)
# following should always gracefully handled, no crashes
ticker.cashflow
ticker.balance_sheet
ticker.financials
ticker.sustainability
ticker.major_holders
ticker.institutional_holders
ticker.mutualfund_holders
print("OK")
# Ford has no institutional investors table or mutual fund holders
ticker = yf.Ticker('F')
print(">> F", end=" ... ")
assert(ticker.info is not None and ticker.info != {})
assert(ticker.major_holders is not None)
assert(ticker.institutional_holders is None)
print("OK")
# NKLA has no institutional investors table or mutual fund holders
ticker = yf.Ticker('NKLA')
print(">> NKLA", end=" ... ")
assert(ticker.info is not None and ticker.info != {})
assert(ticker.major_holders is not None)
assert(ticker.institutional_holders is None)
print("OK")
# NKLA has no institutional investors table or mutual fund holders
ticker = yf.Ticker('NESN.SW')
print(">> NESN.SW", end=" ... ")
assert(ticker.info is not None and ticker.info != {})
assert(ticker.major_holders is not None)
assert(ticker.institutional_holders is None)
print("OK")
if __name__ == "__main__":
test_yfinance()

View File

@@ -1,27 +1,36 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
"""Yahoo! Finance market data downloader (+fix for Pandas Datareader)"""
"""yfinance - market data downloader"""
from setuptools import setup, find_packages
# from codecs import open
import io
from os import path
# --- get version ---
version = "unknown"
with open("yfinance/version.py") as f:
line = f.read().strip()
version = line.replace("version = ", "").replace('"', '')
# --- /get version ---
here = path.abspath(path.dirname(__file__))
# Get the long description from the README file
with io.open(path.join(here, 'README.rst'), encoding='utf-8') as f:
with io.open(path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = f.read()
setup(
name='yfinance',
version="0.1.55",
description='Yahoo! Finance market data downloader',
version=version,
description='Download market data from Yahoo! Finance API',
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/ranaroussi/yfinance',
author='Ran Aroussi',
author_email='ran@aroussi.com',
@@ -44,18 +53,27 @@ setup(
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
# 'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
],
platforms=['any'],
keywords='pandas, yahoo finance, pandas datareader',
packages=find_packages(exclude=['contrib', 'docs', 'tests', 'examples']),
install_requires=['pandas>=0.24', 'numpy>=1.15',
'requests>=2.20', 'multitasking>=0.0.7',
'lxml>=4.5.1'],
install_requires=['pandas>=1.3.0', 'numpy>=1.16.5',
'requests>=2.26', 'multitasking>=0.0.7',
'lxml>=4.9.1', 'appdirs>=1.4.4',
'cryptography>=3.3.2'],
entry_points={
'console_scripts': [
'sample=sample:main',
],
},
)
print("""
NOTE: yfinance is not affiliated, endorsed, or vetted by Yahoo, Inc.
You should refer to Yahoo!'s terms of use for details on your rights
to use the actual data downloaded.""")

134
test_yfinance.py Normal file
View File

@@ -0,0 +1,134 @@
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
"""
Sanity check for most common library uses all working
- Stock: Microsoft
- ETF: Russell 2000 Growth
- Mutual fund: Vanguard 500 Index fund
- Index: S&P500
- Currency BTC-USD
"""
import yfinance as yf
import unittest
import datetime
session = None
import requests_cache ; session = requests_cache.CachedSession("yfinance.cache", expire_after=24*60*60)
# Good symbols = all attributes should work
good_symbols = ['MSFT', 'IWO', 'VFINX', '^GSPC', 'BTC-USD']
good_tickers = [yf.Ticker(symbol, session=session) for symbol in good_symbols]
# Dodgy symbols = Yahoo data incomplete, so exclude from some tests
dodgy_symbols = ["G7W.DU"]
dodgy_tickers = [yf.Ticker(symbol, session=session) for symbol in dodgy_symbols]
symbols = good_symbols + dodgy_symbols
tickers = good_tickers + dodgy_tickers
# Delisted = no data expected but yfinance shouldn't raise exception
delisted_symbols = ["BRK.B", "SDLP"]
delisted_tickers = [yf.Ticker(symbol, session=session) for symbol in delisted_symbols]
class TestTicker(unittest.TestCase):
def setUp(self):
d_today = datetime.date.today()
d_today -= datetime.timedelta(days=30)
self.start_d = datetime.date(d_today.year, d_today.month, 1)
def test_info_history(self):
# always should have info and history for valid symbols
for ticker in tickers:
assert(ticker.info is not None and ticker.info != {})
history = ticker.history(period="1mo")
assert(history.empty is False and history is not None)
histories = yf.download(symbols, period="1mo", session=session)
assert(histories.empty is False and histories is not None)
for ticker in tickers:
assert(ticker.info is not None and ticker.info != {})
history = ticker.history(start=self.start_d)
assert(history.empty is False and history is not None)
histories = yf.download(symbols, start=self.start_d, session=session)
assert(histories.empty is False and histories is not None)
def test_info_history_nofail(self):
# should not throw Exception for delisted tickers, just print a message
for ticker in delisted_tickers:
history = ticker.history(period="1mo")
histories = yf.download(delisted_symbols, period="1mo", session=session)
histories = yf.download(delisted_symbols[0], period="1mo", session=session)
histories = yf.download(delisted_symbols[1], period="1mo")#, session=session)
for ticker in delisted_tickers:
history = ticker.history(start=self.start_d)
histories = yf.download(delisted_symbols, start=self.start_d, session=session)
histories = yf.download(delisted_symbols[0], start=self.start_d, session=session)
histories = yf.download(delisted_symbols[1], start=self.start_d, session=session)
def test_attributes(self):
for ticker in tickers:
ticker.isin
ticker.major_holders
ticker.institutional_holders
ticker.mutualfund_holders
ticker.dividends
ticker.splits
ticker.actions
ticker.info
ticker.info["trailingPegRatio"]
ticker.calendar
ticker.recommendations
ticker.earnings
ticker.quarterly_earnings
ticker.financials
ticker.quarterly_financials
ticker.balance_sheet
ticker.quarterly_balance_sheet
ticker.cashflow
ticker.quarterly_cashflow
ticker.sustainability
ticker.options
ticker.news
ticker.shares
ticker.earnings_history
ticker.earnings_dates
def test_attributes_nofail(self):
# should not throw Exception for delisted tickers, just print a message
for ticker in delisted_tickers:
ticker.isin
ticker.major_holders
ticker.institutional_holders
ticker.mutualfund_holders
ticker.dividends
ticker.splits
ticker.actions
ticker.info
ticker.calendar
ticker.recommendations
ticker.earnings
ticker.quarterly_earnings
ticker.financials
ticker.quarterly_financials
ticker.balance_sheet
ticker.quarterly_balance_sheet
ticker.cashflow
ticker.quarterly_cashflow
ticker.sustainability
ticker.options
ticker.news
ticker.shares
ticker.earnings_history
ticker.earnings_dates
def test_holders(self):
for ticker in good_tickers:
assert(ticker.major_holders is not None)
assert(ticker.institutional_holders is not None)
if __name__ == '__main__':
unittest.main()

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
#
# Copyright 2017-2019 Ran Aroussi
@@ -19,12 +19,14 @@
# limitations under the License.
#
__version__ = "0.1.54"
__author__ = "Ran Aroussi"
from . import version
from .ticker import Ticker
from .tickers import Tickers
from .multi import download
from .utils import set_tz_cache_location
__version__ = version.version
__author__ = "Ran Aroussi"
def pdr_override():
@@ -41,4 +43,4 @@ def pdr_override():
pass
__all__ = ['download', 'Ticker', 'Tickers', 'pdr_override']
__all__ = ['download', 'Ticker', 'Tickers', 'pdr_override', 'set_tz_cache_location']

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
#
# Copyright 2017-2019 Ran Aroussi
@@ -29,10 +29,10 @@ from . import Ticker, utils
from . import shared
def download(tickers, start=None, end=None, actions=False, threads=True,
group_by='column', auto_adjust=False, back_adjust=False,
progress=True, period="max", interval="1d", prepost=False,
proxy=None, rounding=False, **kwargs):
def download(tickers, start=None, end=None, actions=False, threads=True, ignore_tz=True,
group_by='column', auto_adjust=False, back_adjust=False, keepna=False,
progress=True, period="max", show_errors=True, interval="1d", prepost=False,
proxy=None, rounding=False, timeout=None, **kwargs):
"""Download yahoo tickers
:Parameters:
tickers : str, list
@@ -56,20 +56,43 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
Default is False
auto_adjust: bool
Adjust all OHLC automatically? Default is False
keepna: bool
Keep NaN rows returned by Yahoo?
Default is False
actions: bool
Download dividend + stock splits data. Default is False
threads: bool / int
How many threads to use for mass downloading. Default is True
ignore_tz: bool
When combining from different timezones, ignore that part of datetime.
Default is True
proxy: str
Optional. Proxy server URL scheme. Default is None
rounding: bool
Optional. Round values to 2 decimal places?
show_errors: bool
Optional. Doesn't print errors if False
timeout: None or float
If not None stops waiting for a response after given number of
seconds. (Can also be a fraction of a second e.g. 0.01)
"""
# create ticker list
tickers = tickers if isinstance(
tickers, (list, set, tuple)) else tickers.replace(',', ' ').split()
# accept isin as ticker
shared._ISINS = {}
_tickers_ = []
for ticker in tickers:
if utils.is_isin(ticker):
isin = ticker
ticker = utils.get_ticker_by_isin(ticker, proxy)
shared._ISINS[ticker] = isin
_tickers_.append(ticker)
tickers = _tickers_
tickers = list(set([ticker.upper() for ticker in tickers]))
if progress:
@@ -88,9 +111,9 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
_download_one_threaded(ticker, period=period, interval=interval,
start=start, end=end, prepost=prepost,
actions=actions, auto_adjust=auto_adjust,
back_adjust=back_adjust,
back_adjust=back_adjust, keepna=keepna,
progress=(progress and i > 0), proxy=proxy,
rounding=rounding)
rounding=rounding, timeout=timeout)
while len(shared._DFS) < len(tickers):
_time.sleep(0.01)
@@ -100,7 +123,8 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
data = _download_one(ticker, period=period, interval=interval,
start=start, end=end, prepost=prepost,
actions=actions, auto_adjust=auto_adjust,
back_adjust=back_adjust, rounding=rounding)
back_adjust=back_adjust, keepna=keepna, proxy=proxy,
rounding=rounding, timeout=timeout)
shared._DFS[ticker.upper()] = data
if progress:
shared._PROGRESS_BAR.animate()
@@ -108,24 +132,33 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
if progress:
shared._PROGRESS_BAR.completed()
if shared._ERRORS:
if shared._ERRORS and show_errors:
print('\n%.f Failed download%s:' % (
len(shared._ERRORS), 's' if len(shared._ERRORS) > 1 else ''))
# print(shared._ERRORS)
print("\n".join(['- %s: %s' %
v for v in list(shared._ERRORS.items())]))
if ignore_tz:
for tkr in shared._DFS.keys():
if (shared._DFS[tkr] is not None) and (shared._DFS[tkr].shape[0]>0):
shared._DFS[tkr].index = shared._DFS[tkr].index.tz_localize(None)
if len(tickers) == 1:
return shared._DFS[tickers[0]]
ticker = tickers[0]
return shared._DFS[shared._ISINS.get(ticker, ticker)]
try:
data = _pd.concat(shared._DFS.values(), axis=1,
data = _pd.concat(shared._DFS.values(), axis=1, sort=True,
keys=shared._DFS.keys())
except Exception:
_realign_dfs()
data = _pd.concat(shared._DFS.values(), axis=1,
data = _pd.concat(shared._DFS.values(), axis=1, sort=True,
keys=shared._DFS.keys())
# switch names back to isins if applicable
data.rename(columns=shared._ISINS, inplace=True)
if group_by == 'column':
data.columns = data.columns.swaplevel(0, 1)
data.sort_index(level=0, axis=1, inplace=True)
@@ -161,10 +194,11 @@ def _download_one_threaded(ticker, start=None, end=None,
auto_adjust=False, back_adjust=False,
actions=False, progress=True, period="max",
interval="1d", prepost=False, proxy=None,
rounding=False):
keepna=False, rounding=False, timeout=None):
data = _download_one(ticker, start, end, auto_adjust, back_adjust,
actions, period, interval, prepost, proxy, rounding)
actions, period, interval, prepost, proxy, rounding,
keepna, timeout, many=True)
shared._DFS[ticker.upper()] = data
if progress:
shared._PROGRESS_BAR.animate()
@@ -173,10 +207,12 @@ def _download_one_threaded(ticker, start=None, end=None,
def _download_one(ticker, start=None, end=None,
auto_adjust=False, back_adjust=False,
actions=False, period="max", interval="1d",
prepost=False, proxy=None, rounding=False):
prepost=False, proxy=None, rounding=False,
keepna=False, timeout=None, many=False):
return Ticker(ticker).history(period=period, interval=interval,
start=start, end=end, prepost=prepost,
actions=actions, auto_adjust=auto_adjust,
back_adjust=back_adjust, proxy=proxy,
rounding=rounding, many=True)
rounding=rounding, keepna=keepna, timeout=timeout,
many=many)

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
#
# Copyright 2017-2019 Ran Aroussi
@@ -22,3 +22,4 @@
_DFS = {}
_PROGRESS_BAR = None
_ERRORS = {}
_ISINS = {}

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
#
# Copyright 2017-2019 Ran Aroussi
@@ -31,6 +31,7 @@ import pandas as _pd
# import re as _re
from collections import namedtuple as _namedtuple
from . import utils
from .base import TickerBase
@@ -53,13 +54,17 @@ class Ticker(TickerBase):
proxy = proxy["https"]
proxy = {"https": proxy}
r = _requests.get(url=url, proxies=proxy).json()
if r['optionChain']['result']:
r = _requests.get(
url=url,
proxies=proxy,
headers=utils.user_agent_headers
).json()
if len(r.get('optionChain', {}).get('result', [])) > 0:
for exp in r['optionChain']['result'][0]['expirationDates']:
self._expirations[_datetime.datetime.utcfromtimestamp(
exp).strftime('%Y-%m-%d')] = exp
return r['optionChain']['result'][0]['options'][0]
return {}
opt = r['optionChain']['result'][0].get('options', [])
return opt[0] if len(opt) > 0 else []
def _options2df(self, opt, tz=None):
data = _pd.DataFrame(opt).reindex(columns=[
@@ -79,9 +84,9 @@ class Ticker(TickerBase):
'currency'])
data['lastTradeDate'] = _pd.to_datetime(
data['lastTradeDate'], unit='s')
data['lastTradeDate'], unit='s', utc=True)
if tz is not None:
data['lastTradeDate'] = data['lastTradeDate'].tz_localize(tz)
data['lastTradeDate'] = data['lastTradeDate'].dt.tz_convert(tz)
return data
def option_chain(self, date=None, proxy=None, tz=None):
@@ -133,6 +138,10 @@ class Ticker(TickerBase):
def actions(self):
return self.get_actions()
@property
def shares(self):
return self.get_shares()
@property
def info(self):
return self.get_info()
@@ -194,3 +203,19 @@ class Ticker(TickerBase):
if not self._expirations:
self._download_options()
return tuple(self._expirations.keys())
@property
def news(self):
return self.get_news()
@property
def analysis(self):
return self.get_analysis()
@property
def earnings_history(self):
return self.get_earnings_history()
@property
def earnings_dates(self):
return self.get_earnings_dates()

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
#
# Copyright 2017-2019 Ran Aroussi
@@ -22,19 +22,7 @@
from __future__ import print_function
from . import Ticker, multi
from collections import namedtuple as _namedtuple
def genTickers(tickers):
tickers = tickers if isinstance(
tickers, list) else tickers.replace(',', ' ').split()
tickers = [ticker.upper() for ticker in tickers]
ticker_objects = {}
for ticker in tickers:
ticker_objects[ticker] = Ticker(ticker)
return _namedtuple("Tickers", ticker_objects.keys()
)(*ticker_objects.values())
# from collections import namedtuple as _namedtuple
class Tickers():
@@ -42,37 +30,38 @@ class Tickers():
def __repr__(self):
return 'yfinance.Tickers object <%s>' % ",".join(self.symbols)
def __init__(self, tickers):
def __init__(self, tickers, session=None):
tickers = tickers if isinstance(
tickers, list) else tickers.replace(',', ' ').split()
self.symbols = [ticker.upper() for ticker in tickers]
ticker_objects = {}
for ticker in self.symbols:
ticker_objects[ticker] = Ticker(ticker)
ticker_objects[ticker] = Ticker(ticker, session=session)
self.tickers = _namedtuple(
"Tickers", ticker_objects.keys(), rename=True
)(*ticker_objects.values())
self.tickers = ticker_objects
# self.tickers = _namedtuple(
# "Tickers", ticker_objects.keys(), rename=True
# )(*ticker_objects.values())
def history(self, period="1mo", interval="1d",
start=None, end=None, prepost=False,
actions=True, auto_adjust=True, proxy=None,
threads=True, group_by='column', progress=True,
**kwargs):
timeout=None, **kwargs):
return self.download(
period, interval,
start, end, prepost,
actions, auto_adjust, proxy,
threads, group_by, progress,
**kwargs)
period, interval,
start, end, prepost,
actions, auto_adjust, proxy,
threads, group_by, progress,
timeout, **kwargs)
def download(self, period="1mo", interval="1d",
start=None, end=None, prepost=False,
actions=True, auto_adjust=True, proxy=None,
threads=True, group_by='column', progress=True,
**kwargs):
timeout=None, **kwargs):
data = multi.download(self.symbols,
start=start, end=end,
@@ -85,13 +74,23 @@ class Tickers():
group_by='ticker',
threads=threads,
progress=progress,
timeout=timeout,
**kwargs)
for symbol in self.symbols:
getattr(self.tickers, symbol)._history = data[symbol]
self.tickers.get(symbol, {})._history = data[symbol]
if group_by == 'column':
data.columns = data.columns.swaplevel(0, 1)
data.sort_index(level=0, axis=1, inplace=True)
return data
def news(self):
collection = {}
for ticker in self.symbols:
collection[ticker] = []
items = Ticker(ticker).news
for item in items:
collection[ticker].append(item)
return collection

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Yahoo! Finance market data downloader (+fix for Pandas Datareader)
# yfinance - market data downloader
# https://github.com/ranaroussi/yfinance
#
# Copyright 2017-2019 Ran Aroussi
@@ -21,12 +21,30 @@
from __future__ import print_function
import datetime as _datetime
import pytz as _tz
import requests as _requests
import re as _re
import pandas as _pd
import numpy as _np
import sys as _sys
import re as _re
import os as _os
import appdirs as _ad
from base64 import b64decode
import hashlib
usePycryptodome = False # slightly faster
# usePycryptodome = True
if usePycryptodome:
# NOTE: if decide to use 'pycryptodome', set min version to 3.6.6
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad
else:
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from threading import Lock
mutex = Lock()
try:
import ujson as _json
@@ -34,6 +52,54 @@ except ImportError:
import json as _json
user_agent_headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
def is_isin(string):
return bool(_re.match("^([A-Z]{2})([A-Z0-9]{9})([0-9]{1})$", string))
def get_all_by_isin(isin, proxy=None, session=None):
if not(is_isin(isin)):
raise ValueError("Invalid ISIN number")
from .base import _BASE_URL_
session = session or _requests
url = "{}/v1/finance/search?q={}".format(_BASE_URL_, isin)
data = session.get(url=url, proxies=proxy, headers=user_agent_headers)
try:
data = data.json()
ticker = data.get('quotes', [{}])[0]
return {
'ticker': {
'symbol': ticker['symbol'],
'shortname': ticker['shortname'],
'longname': ticker['longname'],
'type': ticker['quoteType'],
'exchange': ticker['exchDisp'],
},
'news': data.get('news', [])
}
except Exception:
return {}
def get_ticker_by_isin(isin, proxy=None, session=None):
data = get_all_by_isin(isin, proxy, session)
return data.get('ticker', {}).get('symbol', '')
def get_info_by_isin(isin, proxy=None, session=None):
data = get_all_by_isin(isin, proxy, session)
return data.get('ticker', {})
def get_news_by_isin(isin, proxy=None, session=None):
data = get_all_by_isin(isin, proxy, session)
return data.get('news', {})
def empty_df(index=[]):
empty = _pd.DataFrame(index=index, data={
'Open': _np.nan, 'High': _np.nan, 'Low': _np.nan,
@@ -42,18 +108,127 @@ def empty_df(index=[]):
return empty
def get_json(url, proxy=None):
html = _requests.get(url=url, proxies=proxy).text
def empty_earnings_dates_df():
empty = _pd.DataFrame(
columns=["Symbol", "Company", "Earnings Date",
"EPS Estimate", "Reported EPS", "Surprise(%)"])
return empty
if "QuoteSummaryStore" not in html:
html = _requests.get(url=url, proxies=proxy).text
if "QuoteSummaryStore" not in html:
return {}
def get_html(url, proxy=None, session=None):
session = session or _requests
html = session.get(url=url, proxies=proxy, headers=user_agent_headers).text
return html
def decrypt_cryptojs_stores(data):
"""
Yahoo has started encrypting data stores, this method decrypts it.
:param data: Python dict of the json data
:return: The decrypted string data in data['context']['dispatcher']['stores']
"""
_cs = data["_cs"]
# Assumes _cr has format like: '{"words":[-449732894,601032952,157396918,2056341829],"sigBytes":16}';
_cr = _json.loads(data["_cr"])
_cr = b"".join(int.to_bytes(i, length=4, byteorder="big", signed=True) for i in _cr["words"])
password = hashlib.pbkdf2_hmac("sha1", _cs.encode("utf8"), _cr, 1, dklen=32).hex()
encrypted_stores = data['context']['dispatcher']['stores']
encrypted_stores = b64decode(encrypted_stores)
assert encrypted_stores[0:8] == b"Salted__"
salt = encrypted_stores[8:16]
encrypted_stores = encrypted_stores[16:]
key, iv = _EVPKDF(password, salt, keySize=32, ivSize=16, iterations=1, hashAlgorithm="md5")
if usePycryptodome:
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
plaintext = cipher.decrypt(encrypted_stores)
plaintext = unpad(plaintext, 16, style="pkcs7")
else:
cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
decryptor = cipher.decryptor()
plaintext = decryptor.update(encrypted_stores) + decryptor.finalize()
unpadder = padding.PKCS7(128).unpadder()
plaintext = unpadder.update(plaintext) + unpadder.finalize()
plaintext = plaintext.decode("utf-8")
return plaintext
def _EVPKDF(password, salt, keySize=32, ivSize=16, iterations=1, hashAlgorithm="md5") -> tuple:
"""OpenSSL EVP Key Derivation Function
Args:
password (Union[str, bytes, bytearray]): Password to generate key from.
salt (Union[bytes, bytearray]): Salt to use.
keySize (int, optional): Output key length in bytes. Defaults to 32.
ivSize (int, optional): Output Initialization Vector (IV) length in bytes. Defaults to 16.
iterations (int, optional): Number of iterations to perform. Defaults to 1.
hashAlgorithm (str, optional): Hash algorithm to use for the KDF. Defaults to 'md5'.
Returns:
key, iv: Derived key and Initialization Vector (IV) bytes.
Taken from: https://gist.github.com/rafiibrahim8/0cd0f8c46896cafef6486cb1a50a16d3
OpenSSL original code: https://github.com/openssl/openssl/blob/master/crypto/evp/evp_key.c#L78
"""
assert iterations > 0, "Iterations can not be less than 1."
if isinstance(password, str):
password = password.encode("utf-8")
final_length = keySize + ivSize
key_iv = b""
block = None
while len(key_iv) < final_length:
hasher = hashlib.new(hashAlgorithm)
if block:
hasher.update(block)
hasher.update(password)
hasher.update(salt)
block = hasher.digest()
for _ in range(1, iterations):
block = hashlib.new(hashAlgorithm, block).digest()
key_iv += block
key, iv = key_iv[:keySize], key_iv[keySize:final_length]
return key, iv
def get_json(url, proxy=None, session=None):
session = session or _requests
html = session.get(url=url, proxies=proxy, headers=user_agent_headers).text
if not "root.App.main =" in html:
return {}
json_str = html.split('root.App.main =')[1].split(
'(this)')[0].split(';\n}')[0].strip()
data = _json.loads(json_str)[
'context']['dispatcher']['stores']['QuoteSummaryStore']
data = _json.loads(json_str)
if "_cs" in data and "_cr" in data:
data_stores = _json.loads(decrypt_cryptojs_stores(data))
else:
if "context" in data and "dispatcher" in data["context"]:
# Keep old code, just in case
data_stores = data['context']['dispatcher']['stores']
else:
data_stores = data
if not 'QuoteSummaryStore' in data_stores:
# Problem in data. Either delisted, or Yahoo spam triggered
return {}
data = data_stores['QuoteSummaryStore']
# add data about Shares Outstanding for companies' tickers if they are available
try:
data['annualBasicAverageShares'] = \
data_stores['QuoteTimeSeriesStore']['timeSeries']['annualBasicAverageShares']
except Exception:
pass
# return data
new_data = _json.dumps(data).replace('{}', 'null')
@@ -67,6 +242,23 @@ def camel2title(o):
return [_re.sub("([a-z])([A-Z])", r"\g<1> \g<2>", i).title() for i in o]
def _parse_user_dt(dt, exchange_tz):
if isinstance(dt, int):
## Should already be epoch, test with conversion:
_datetime.datetime.fromtimestamp(dt)
else:
# Convert str/date -> datetime, set tzinfo=exchange, get timestamp:
if isinstance(dt, str):
dt = _datetime.datetime.strptime(str(dt), '%Y-%m-%d')
if isinstance(dt, _datetime.date) and not isinstance(dt, _datetime.datetime):
dt = _datetime.datetime.combine(dt, _datetime.time(0))
if isinstance(dt, _datetime.datetime) and dt.tzinfo is None:
# Assume user is referring to exchange's timezone
dt = _tz.timezone(exchange_tz).localize(dt)
dt = int(dt.timestamp())
return dt
def auto_adjust(data):
df = data.copy()
ratio = df["Close"] / df["Adj Close"]
@@ -108,7 +300,7 @@ def back_adjust(data):
return df[["Open", "High", "Low", "Close", "Volume"]]
def parse_quotes(data, tz=None):
def parse_quotes(data):
timestamps = data["timestamp"]
ohlc = data["indicators"]["quote"][0]
volumes = ohlc["volume"]
@@ -131,15 +323,14 @@ def parse_quotes(data, tz=None):
quotes.index = _pd.to_datetime(timestamps, unit="s")
quotes.sort_index(inplace=True)
if tz is not None:
quotes.index = quotes.index.tz_localize(tz)
return quotes
def parse_actions(data, tz=None):
dividends = _pd.DataFrame(columns=["Dividends"])
splits = _pd.DataFrame(columns=["Stock Splits"])
def parse_actions(data):
dividends = _pd.DataFrame(
columns=["Dividends"], index=_pd.DatetimeIndex([]))
splits = _pd.DataFrame(
columns=["Stock Splits"], index=_pd.DatetimeIndex([]))
if "events" in data:
if "dividends" in data["events"]:
@@ -148,8 +339,6 @@ def parse_actions(data, tz=None):
dividends.set_index("date", inplace=True)
dividends.index = _pd.to_datetime(dividends.index, unit="s")
dividends.sort_index(inplace=True)
if tz is not None:
dividends.index = dividends.index.tz_localize(tz)
dividends.columns = ["Dividends"]
@@ -159,8 +348,6 @@ def parse_actions(data, tz=None):
splits.set_index("date", inplace=True)
splits.index = _pd.to_datetime(splits.index, unit="s")
splits.sort_index(inplace=True)
if tz is not None:
splits.index = splits.index.tz_localize(tz)
splits["Stock Splits"] = splits["numerator"] / \
splits["denominator"]
splits = splits["Stock Splits"]
@@ -168,6 +355,19 @@ def parse_actions(data, tz=None):
return dividends, splits
def fix_Yahoo_dst_issue(df, interval):
if interval in ["1d","1w","1wk"]:
# These intervals should start at time 00:00. But for some combinations of date and timezone,
# Yahoo has time off by few hours (e.g. Brazil 23:00 around Jan-2022). Suspect DST problem.
# The clue is (a) minutes=0 and (b) hour near 0.
# Obviously Yahoo meant 00:00, so ensure this doesn't affect date conversion:
f_pre_midnight = (df.index.minute == 0) & (df.index.hour.isin([22,23]))
dst_error_hours = _np.array([0]*df.shape[0])
dst_error_hours[f_pre_midnight] = 24-df.index[f_pre_midnight].hour
df.index += _pd.TimedeltaIndex(dst_error_hours, 'h')
return df
class ProgressBar:
def __init__(self, iterations, text='completed'):
self.text = text
@@ -216,3 +416,55 @@ class ProgressBar:
def __str__(self):
return str(self.prog_bar)
# Simple file cache of ticker->timezone:
_cache_dp = None
def get_cache_dirpath():
if _cache_dp is None:
dp = _os.path.join(_ad.user_cache_dir(), "py-yfinance")
else:
dp = _os.path.join(_cache_dp, "py-yfinance")
return dp
def set_tz_cache_location(dp):
global _cache_dp
_cache_dp = dp
def cache_lookup_tkr_tz(tkr):
fp = _os.path.join(get_cache_dirpath(), "tkr-tz.csv")
if not _os.path.isfile(fp):
return None
mutex.acquire()
df = _pd.read_csv(fp, index_col="Ticker", on_bad_lines="skip")
mutex.release()
if tkr in df.index:
return df.loc[tkr,"Tz"]
else:
return None
def cache_store_tkr_tz(tkr,tz):
dp = get_cache_dirpath()
fp = _os.path.join(dp, "tkr-tz.csv")
mutex.acquire()
if not _os.path.isdir(dp):
_os.makedirs(dp)
if (not _os.path.isfile(fp)) and (tz is not None):
df = _pd.DataFrame({"Tz":[tz]}, index=[tkr])
df.index.name = "Ticker"
df.to_csv(fp)
else:
df = _pd.read_csv(fp, index_col="Ticker", on_bad_lines="skip")
if tz is None:
# Delete if in cache:
if tkr in df.index:
df.drop(tkr).to_csv(fp)
else:
if tkr in df.index:
raise Exception("Tkr {} tz already in cache".format(tkr))
df.loc[tkr,"Tz"] = tz
df.to_csv(fp)
mutex.release()

1
yfinance/version.py Normal file
View File

@@ -0,0 +1 @@
version = "0.1.96"