Compare commits
191 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea4dc2d22a | ||
|
|
b29cc269c6 | ||
|
|
8db46f2b12 | ||
|
|
f8e75b3aaf | ||
|
|
8f04f91e2b | ||
|
|
4a1e1a9fb2 | ||
|
|
a05a759852 | ||
|
|
9b7f53689b | ||
|
|
31109b2a2a | ||
|
|
8e88aec77d | ||
|
|
068e6b04db | ||
|
|
90575a029f | ||
|
|
5dbc2950e8 | ||
|
|
4707bc035e | ||
|
|
81011a7a75 | ||
|
|
14ec3df9a4 | ||
|
|
1056487183 | ||
|
|
b7a425d683 | ||
|
|
a61e0a07b5 | ||
|
|
e2150daf18 | ||
|
|
69dbf74292 | ||
|
|
b5c2160837 | ||
|
|
b8ab067caa | ||
|
|
c6429482ab | ||
|
|
4f9b6d6e9f | ||
|
|
5812aa6a69 | ||
|
|
ea810b4b35 | ||
|
|
53bce46929 | ||
|
|
0eb11c56b0 | ||
|
|
2981893f30 | ||
|
|
3250386136 | ||
|
|
aa606642c0 | ||
|
|
cc0b03efd1 | ||
|
|
39dd87080d | ||
|
|
72a2fd8955 | ||
|
|
dd62ce510e | ||
|
|
61ceb2b1a8 | ||
|
|
5d7a298239 | ||
|
|
0192d2e194 | ||
|
|
8c6eb1afeb | ||
|
|
ef60663bc2 | ||
|
|
d15cf378a1 | ||
|
|
a9282e5739 | ||
|
|
a506838c3c | ||
|
|
f716eec5fe | ||
|
|
e769570f33 | ||
|
|
3bc6bacf56 | ||
|
|
7db82f3496 | ||
|
|
4ac5cd87b3 | ||
|
|
4a91008c09 | ||
|
|
de0760eec8 | ||
|
|
55bc1bdced | ||
|
|
b509dc9551 | ||
|
|
bb6ebb4b84 | ||
|
|
d08afa21fc | ||
|
|
5bd805b3f6 | ||
|
|
54c6ac3ed7 | ||
|
|
68b7c16162 | ||
|
|
78ad990371 | ||
|
|
81d8737a25 | ||
|
|
946a84bf20 | ||
|
|
890026c862 | ||
|
|
22e4219ec7 | ||
|
|
ac9184bf18 | ||
|
|
745d554aae | ||
|
|
ec5548bd85 | ||
|
|
63b56a799a | ||
|
|
d1dde1814d | ||
|
|
4c23d339bc | ||
|
|
3b36df048b | ||
|
|
6f0f408880 | ||
|
|
9158d3c119 | ||
|
|
2608f3660c | ||
|
|
e614e6b8ff | ||
|
|
75510557ea | ||
|
|
4c609b42c6 | ||
|
|
c5209cad3b | ||
|
|
8ad7b89a9a | ||
|
|
615db18a96 | ||
|
|
537dd468f2 | ||
|
|
5fd0d0f66f | ||
|
|
fcecf2aa59 | ||
|
|
ad33ab9b77 | ||
|
|
5a3ab9c044 | ||
|
|
7db2572799 | ||
|
|
11ef919e88 | ||
|
|
0e5fb9614f | ||
|
|
af87fbbd53 | ||
|
|
d07e2061a3 | ||
|
|
40aa002867 | ||
|
|
71e692a268 | ||
|
|
45e8d6f6f7 | ||
|
|
1fcf8ad57e | ||
|
|
2c93db3a79 | ||
|
|
fc5d29558b | ||
|
|
290bf9b7cf | ||
|
|
13b26a99d0 | ||
|
|
c399feabe6 | ||
|
|
e0fdd5823f | ||
|
|
1ed7c39e94 | ||
|
|
fee9af07ce | ||
|
|
d64777c6e7 | ||
|
|
b8ae8f317f | ||
|
|
cfc7142c56 | ||
|
|
89f1934bd6 | ||
|
|
07651ed2f4 | ||
|
|
b1bb75113c | ||
|
|
a358c8848f | ||
|
|
fbe9f8f119 | ||
|
|
00fec80f63 | ||
|
|
81c6b2d2e6 | ||
|
|
29162bdd01 | ||
|
|
587fdd032b | ||
|
|
8cc002ecbf | ||
|
|
092a0c8193 | ||
|
|
8908724f3c | ||
|
|
4ecd6a67cf | ||
|
|
f3f6739153 | ||
|
|
9c9f305b0a | ||
|
|
509a33b71d | ||
|
|
6af17db77d | ||
|
|
5cc1197c5f | ||
|
|
21a80ec719 | ||
|
|
ca011b0738 | ||
|
|
f26b436e0a | ||
|
|
f208f09336 | ||
|
|
f831ac2c1b | ||
|
|
e195f2c6c5 | ||
|
|
db5d0c9207 | ||
|
|
918eb31583 | ||
|
|
390422fe6b | ||
|
|
3a7b802b20 | ||
|
|
287536ad15 | ||
|
|
25035a0ff3 | ||
|
|
383b60d349 | ||
|
|
f28284a42d | ||
|
|
fa3094daed | ||
|
|
102e266eab | ||
|
|
31cc2439f7 | ||
|
|
9b74b4e11f | ||
|
|
41426f6678 | ||
|
|
f09bc07ecc | ||
|
|
dba0cba00b | ||
|
|
eeb2d483d3 | ||
|
|
9a6f147de5 | ||
|
|
7be3069b6f | ||
|
|
70c84a3482 | ||
|
|
ae8720f007 | ||
|
|
c388ca73e8 | ||
|
|
7709bc6ae3 | ||
|
|
9b33910a98 | ||
|
|
0ed941c2f5 | ||
|
|
f2a8d01a13 | ||
|
|
403607c721 | ||
|
|
604f74ea5e | ||
|
|
95b59a7d53 | ||
|
|
0b8ae726cb | ||
|
|
1ddc38c04f | ||
|
|
fcab4ea37e | ||
|
|
90053ab7c3 | ||
|
|
d40ad6282a | ||
|
|
c95c02fdfc | ||
|
|
5fb9cab817 | ||
|
|
1c39ca4762 | ||
|
|
27868a4677 | ||
|
|
0da75493dc | ||
|
|
14c6d05854 | ||
|
|
8e369a2736 | ||
|
|
e09f77eb06 | ||
|
|
7db798e900 | ||
|
|
3b7758b3ab | ||
|
|
b729bcb1df | ||
|
|
6d7c5b6f4c | ||
|
|
45568fd765 | ||
|
|
fc020d953a | ||
|
|
bc645bb7dd | ||
|
|
74198aeed4 | ||
|
|
890922f68b | ||
|
|
44ef4a73ac | ||
|
|
c745df183a | ||
|
|
0e069dbbff | ||
|
|
25144351a4 | ||
|
|
3dd7e40df2 | ||
|
|
5bbcedfe2e | ||
|
|
fc049e1e0d | ||
|
|
92c3b9066a | ||
|
|
00a44a8132 | ||
|
|
94327906df | ||
|
|
07474123a2 | ||
|
|
0be2ce1fd5 | ||
|
|
2fc0907217 |
14
.github/ISSUE_TEMPLATE/bug_report.yaml
vendored
@@ -18,7 +18,15 @@ body:
|
||||
|
||||
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.
|
||||
Then visit `finance.yahoo.com` and confirm they have the data you want. Maybe your symbol was delisted.
|
||||
|
||||
### Data is wrong
|
||||
|
||||
**yfinance is not affiliated with Yahoo**. If Yahoo Finance website data is bad, tell Yahoo: https://help.yahoo.com/kb/finance-for-web/report-problems-feedback-ideas-yahoo-finance-sln28397.html.
|
||||
|
||||
But if yfinance is creating error during processing, then finish this form.
|
||||
|
||||
For price errors, try price repair: https://ranaroussi.github.io/yfinance/advanced/price_repair.html
|
||||
|
||||
### Are you spamming Yahoo?
|
||||
|
||||
@@ -54,7 +62,7 @@ body:
|
||||
- type: textarea
|
||||
id: debug-log
|
||||
attributes:
|
||||
label: "Debug log"
|
||||
label: "Debug log from yf.enable_debug_mode()"
|
||||
description: "Run code with debug logging enabled - `yf.enable_debug_mode()` - and post the full output. Context: https://github.com/ranaroussi/yfinance/tree/main#logging"
|
||||
validations:
|
||||
required: true
|
||||
@@ -63,7 +71,7 @@ body:
|
||||
id: bad-data-proof
|
||||
attributes:
|
||||
label: "Bad data proof"
|
||||
description: "If `yfinance` returning bad data, show proof here. Best is screenshot of finance.yahoo.com"
|
||||
description: "If yfinance returning bad data, show proof of good data on Yahoo Finance website here."
|
||||
validations:
|
||||
required: false
|
||||
|
||||
|
||||
36
.github/workflows/auto_close_default_issues.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Auto-close issues using default template
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
check-template:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check if issue uses custom template
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const issue = context.payload.issue;
|
||||
const body = issue.body || '';
|
||||
|
||||
// Check for specific fields from your custom form
|
||||
// Adjust these patterns based on your form structure
|
||||
const hasCustomFields = body.includes('### Describe bug') ||
|
||||
body.includes('### Simple code that reproduces');
|
||||
|
||||
if (!hasCustomFields) {
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
body: 'This issue appears to use the default template. Stop that. Use our custom bug report form.'
|
||||
});
|
||||
|
||||
await github.rest.issues.update({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue.number,
|
||||
state: 'closed'
|
||||
});
|
||||
}
|
||||
3
.github/workflows/deploy_doc.yml
vendored
@@ -3,7 +3,8 @@ name: Build and Deploy Sphinx Docs
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev-documented
|
||||
- main
|
||||
# - dev-documented
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
|
||||
35
.github/workflows/pytest.yml.disabled
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
name: Pytest
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- main
|
||||
- dev
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt pytest
|
||||
|
||||
- name: Run non-cache tests
|
||||
run: pytest tests/ --ignore tests/test_cache.py --ignore tests/test_price_repair.py
|
||||
|
||||
- name: Run cache tests
|
||||
run: |
|
||||
pytest tests/test_cache.py::TestCache
|
||||
pytest tests/test_cache.py::TestCacheNoPermission
|
||||
6
.github/workflows/ruff.yml
vendored
@@ -9,5 +9,7 @@ jobs:
|
||||
ruff:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: chartboost/ruff-action@v1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
args: check . --exclude yfinance/pricing_pb2.py
|
||||
|
||||
3
.gitignore
vendored
@@ -9,7 +9,6 @@ yfinance.egg-info
|
||||
build/
|
||||
*.html
|
||||
*.css
|
||||
*.png
|
||||
test.ipynb
|
||||
|
||||
# Environments
|
||||
@@ -24,4 +23,4 @@ ENV/
|
||||
/doc/_build/
|
||||
/doc/source/reference/api
|
||||
!yfinance.css
|
||||
!/doc/source/development/assets/branches.png
|
||||
!/doc/source/development/assets/branches.png
|
||||
|
||||
101
CHANGELOG.rst
@@ -1,6 +1,107 @@
|
||||
Change Log
|
||||
===========
|
||||
|
||||
0.2.65
|
||||
------
|
||||
Financials: ensure dtype float #2563
|
||||
Prices: fix handling arguments start/end/period #2561 #2562
|
||||
Price repair: when changing FX, update metadata #2558
|
||||
|
||||
0.2.64
|
||||
------
|
||||
Prices:
|
||||
- handle dividends with FX, convert if repair=True #2549
|
||||
- fix 'period' arg when start or end set #2550
|
||||
earnings_dates: handle 'Event Type' properly #2555
|
||||
|
||||
0.2.63
|
||||
------
|
||||
Fix download(ISIN) # 2531
|
||||
|
||||
0.2.62
|
||||
------
|
||||
Fix prices 'period=max' sometimes failing # 2509
|
||||
ISIN cache #2516
|
||||
Proxy:
|
||||
- fix false 'proxy deprecated' messages
|
||||
- fix ISIN + proxy #2514
|
||||
- replace print_once with warnings #2523
|
||||
Error handling:
|
||||
- detect rate-limit during crumb fetch #2491
|
||||
- replace requests.HTTPError with curl_cffi
|
||||
|
||||
0.2.61
|
||||
------
|
||||
Fix ALL type hints in websocket #2493
|
||||
|
||||
0.2.60
|
||||
------
|
||||
Fix cookie reuse, and handle DNS blocking fc.yahoo.com #2483
|
||||
Fixes for websocket:
|
||||
- relax protobuf version #2485
|
||||
- increase websockets version #2485
|
||||
- fix type hints #2488
|
||||
Fix predefined screen offset #2440
|
||||
|
||||
0.2.59
|
||||
------
|
||||
Fix the fix for rate-limit #2452
|
||||
Feature: live price data websocket #2201
|
||||
|
||||
0.2.58
|
||||
------
|
||||
Fix false rate-limit problem #2430
|
||||
Fix predefined screen size/count #2425
|
||||
|
||||
0.2.57
|
||||
------
|
||||
Fix proxy msg & pass-thru #2418
|
||||
|
||||
0.2.56
|
||||
------
|
||||
Features:
|
||||
- Ticker lookups #2364
|
||||
- Config #2391
|
||||
Fixes:
|
||||
- converting end epoch to localized dt #2378
|
||||
- info IndexError #2382
|
||||
- AttributeError: module 'requests.cookies' has no attribute 'update' #2388
|
||||
- fix_Yahoo_returning_live_separate() #2389
|
||||
|
||||
0.2.55
|
||||
------
|
||||
Features
|
||||
- TTM financials #2321
|
||||
Fixes
|
||||
- info IndexError #2354
|
||||
- earnings dates TZ #2366
|
||||
- price repair tweaks & fixes #2368
|
||||
- history caching #2345
|
||||
- backup fetch TZ from info #2369
|
||||
Maintenance
|
||||
- log user agent #2326
|
||||
|
||||
0.2.54
|
||||
------
|
||||
Hotfix user-agent #2277
|
||||
|
||||
0.2.53
|
||||
------
|
||||
Fixes:
|
||||
- Fix: Failed to parse holders JSON data #2234
|
||||
- Fix: Bad data in Holders #2244
|
||||
- Stop CSRF-cookie-fetch fail killing yfinance #2249
|
||||
- Fix Market Docs #2250
|
||||
- Fix: Broken "See also" links in documentation #2253
|
||||
- Fix: Interval check and error message formatting in multi.py #2256
|
||||
Improve:
|
||||
- Add pre- / post-stock prices (and other useful information) #2212
|
||||
- Warn user when use download() without specifying auto_adjust #2230
|
||||
- Refactor: Earnings Dates – Switch to API Fetching #2247
|
||||
- Improve prices div repair #2260
|
||||
Maintenance:
|
||||
- Add GitHub Actions workflow and fix failing tests #2233
|
||||
|
||||
0.2.52
|
||||
------
|
||||
Features:
|
||||
|
||||
60
CONTRIBUTING.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Contributing
|
||||
|
||||
yfinance relies on the community to investigate bugs and contribute code.
|
||||
|
||||
This is a quick short guide, full guide at https://ranaroussi.github.io/yfinance/development/index.html
|
||||
|
||||
## Branches
|
||||
|
||||
YFinance uses a two-layer branch model:
|
||||
|
||||
* **dev**: new features & most bug-fixes merged here, tested together, conflicts fixed, etc.
|
||||
* **main**: stable branch where PIP releases are created.
|
||||
|
||||
## Running a branch
|
||||
|
||||
```bash
|
||||
pip install git+ranaroussi/yfinance.git@dev # <- dev branch
|
||||
```
|
||||
|
||||
https://ranaroussi.github.io/yfinance/development/running.html
|
||||
|
||||
### I'm a GitHub newbie, how do I contribute code?
|
||||
|
||||
1. Fork this project. If already forked, remember to `Sync fork`
|
||||
|
||||
2. Implement your change in your fork, ideally in a specific branch
|
||||
|
||||
3. Create a [Pull Request](https://github.com/ranaroussi/yfinance/pulls), from your fork to this project. If addressing an Issue, link to it
|
||||
|
||||
https://ranaroussi.github.io/yfinance/development/code.html
|
||||
|
||||
## Documentation website
|
||||
|
||||
The new docs website is generated automatically from code. https://ranaroussi.github.io/yfinance/index.html
|
||||
|
||||
Remember to updates docs when you change code, and check docs locally.
|
||||
|
||||
https://ranaroussi.github.io/yfinance/development/documentation.html
|
||||
|
||||
## Git tricks
|
||||
|
||||
Help keep the Git commit history and [network graph](https://github.com/ranaroussi/yfinance/network) compact:
|
||||
|
||||
* got a long descriptive commit message? `git commit -m "short sentence summary" -m "full commit message"`
|
||||
|
||||
* combine multiple commits into 1 with `git squash`
|
||||
|
||||
* `git rebase` is your friend: change base branch, or "merge in" updates
|
||||
|
||||
https://ranaroussi.github.io/yfinance/development/code.html#git-stuff
|
||||
|
||||
## Unit tests
|
||||
|
||||
Tests have been written using the built-in Python module `unittest`. Examples:
|
||||
|
||||
* Run all tests: `python -m unittest discover -s tests`
|
||||
|
||||
https://ranaroussi.github.io/yfinance/development/testing.html
|
||||
|
||||
> See the [Developer Guide](https://ranaroussi.github.io/yfinance/development/contributing.html#GIT-STUFF) for more information.
|
||||
63
README.md
@@ -1,51 +1,50 @@
|
||||
<img src="./doc/yfinance-gh-logo-dark.webp#gh-dark-mode-only" height="100">
|
||||
<img src="./doc/yfinance-gh-logo-light.webp#gh-light-mode-only" height="100">
|
||||
|
||||
# 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://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>
|
||||
<a target="new" href="https://x.com/intent/follow?screen_name=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 Pythonic way to fetch financial & market data from [Yahoo!Ⓡ finance](https://finance.yahoo.com).
|
||||
|
||||
---
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **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.**
|
||||
|
||||
---
|
||||
|
||||
> [!TIP]
|
||||
> THE NEW DOCUMENTATION WEBSITE IS NOW LIVE! 🤘
|
||||
>
|
||||
> Visit [**ranaroussi.github.io/yfinance**](https://ranaroussi.github.io/yfinance)
|
||||
|
||||
---
|
||||
|
||||
## Main components
|
||||
|
||||
- `Ticker`: single ticker data
|
||||
- `Tickers`: multiple tickers' data
|
||||
- `download`: download market data for multiple tickers
|
||||
- `Market`: get infomation about a market
|
||||
- `Market`: get information about a market
|
||||
- `WebSocket` and `AsyncWebSocket`: live streaming data
|
||||
- `Search`: quotes and news from search
|
||||
- `Sector` and `Industry`: sector and industry information
|
||||
- `EquityQuery` and `Screener`: build query to screen market
|
||||
|
||||
## **NEW DOCUMENTATION WEBSITE**: [ranaroussi.github.io/yfinance](https://ranaroussi.github.io/yfinance/index.html)
|
||||
|
||||
## Installation
|
||||
|
||||
Install `yfinance` from PYPI using `pip`:
|
||||
@@ -54,11 +53,11 @@ Install `yfinance` from PYPI using `pip`:
|
||||
$ pip install yfinance
|
||||
```
|
||||
|
||||
The list of changes can be found in the [Changelog](https://github.com/ranaroussi/yfinance/blob/main/CHANGELOG.rst)
|
||||
### [yfinance relies on the community to investigate bugs and contribute code. Here's how you can help.](CONTRIBUTING.md)
|
||||
|
||||
## Developers: want to contribute?
|
||||
---
|
||||
|
||||
`yfinance` relies on community to investigate bugs, review code, and contribute code. Developer guide: https://github.com/ranaroussi/yfinance/discussions/1084
|
||||

|
||||
|
||||
---
|
||||
|
||||
|
||||
BIN
doc/source/_static/images/repair-prices-100x.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
doc/source/_static/images/repair-prices-missing-div-adjust.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
doc/source/_static/images/repair-prices-missing-row.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
doc/source/_static/images/repair-prices-missing-split-adjust.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
doc/source/_static/images/repair-prices-missing-volume-daily.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 17 KiB |
BIN
doc/source/_static/logo-dark.webp
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
doc/source/_static/logo-light.webp
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
@@ -1,47 +1,6 @@
|
||||
Caching
|
||||
=======
|
||||
|
||||
Smarter Scraping
|
||||
----------------
|
||||
|
||||
Install the `nospam` package to cache API calls and reduce spam to Yahoo:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install yfinance[nospam]
|
||||
|
||||
To use a custom `requests` session, pass a `session=` argument to
|
||||
the Ticker constructor. This allows for caching calls to the API as well as a custom way to modify requests via the `User-agent` header.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import requests_cache
|
||||
session = requests_cache.CachedSession('yfinance.cache')
|
||||
session.headers['User-agent'] = 'my-program/1.0'
|
||||
ticker = yf.Ticker('MSFT', session=session)
|
||||
|
||||
# The scraped response will be stored in the cache
|
||||
ticker.actions
|
||||
|
||||
|
||||
Combine `requests_cache` with rate-limiting to avoid triggering Yahoo's rate-limiter/blocker that can corrupt data.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from requests import Session
|
||||
from requests_cache import CacheMixin, SQLiteCache
|
||||
from requests_ratelimiter import LimiterMixin, MemoryQueueBucket
|
||||
from pyrate_limiter import Duration, RequestRate, Limiter
|
||||
class CachedLimiterSession(CacheMixin, LimiterMixin, Session):
|
||||
pass
|
||||
|
||||
session = CachedLimiterSession(
|
||||
limiter=Limiter(RequestRate(2, Duration.SECOND*5)), # max 2 requests per 5 seconds
|
||||
bucket_class=MemoryQueueBucket,
|
||||
backend=SQLiteCache("yfinance.cache"),
|
||||
)
|
||||
|
||||
|
||||
Persistent Cache
|
||||
----------------
|
||||
|
||||
|
||||
15
doc/source/advanced/config.rst
Normal file
@@ -0,0 +1,15 @@
|
||||
******
|
||||
Config
|
||||
******
|
||||
|
||||
`yfinance` has a new global config for sharing common values.
|
||||
|
||||
Proxy
|
||||
-----
|
||||
|
||||
Set proxy once in config, affects all yfinance data fetches.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import yfinance as yf
|
||||
yf.set_config(proxy="PROXY_SERVER")
|
||||
@@ -6,6 +6,7 @@ Advanced
|
||||
:maxdepth: 2
|
||||
|
||||
logging
|
||||
proxy
|
||||
config
|
||||
caching
|
||||
multi_level_columns
|
||||
multi_level_columns
|
||||
price_repair
|
||||
277
doc/source/advanced/price_repair.rst
Normal file
@@ -0,0 +1,277 @@
|
||||
************
|
||||
Price Repair
|
||||
************
|
||||
|
||||
The new argument ``repair=True`` in ``history()`` and ``download()`` will attempt to fix a variety of price errors caused by Yahoo. Only US market data appears perfect, I guess Yahoo doesn't care much about rest of world?
|
||||
|
||||
The returned table will have a new column ``Repaired?`` that specifies if row was repaired.
|
||||
|
||||
Price repair
|
||||
============
|
||||
|
||||
Missing dividend adjustment
|
||||
---------------------------
|
||||
|
||||
If dividend in data but preceding ``Adj Close`` = ``Close``, then manually apply dividend-adjustment to ``Adj Close``.
|
||||
Note: ``Repaired?`` is NOT set to ``True`` because fix only changes ``Adj Close``
|
||||
|
||||
.. figure:: /_static/images/repair-prices-missing-div-adjust.png
|
||||
:alt: 8TRA.DE: repair missing dividend adjustment
|
||||
:width: 80%
|
||||
:align: left
|
||||
|
||||
8TRA.DE
|
||||
|
||||
.. container:: clearer
|
||||
|
||||
..
|
||||
|
||||
Missing split adjustment
|
||||
------------------------
|
||||
|
||||
If stock split in data but preceding price data is not adjusted, then manually apply stock split.
|
||||
Requires date range include 1 day after stock split for calibration - sometimes Yahoo fails to adjust prices on stock split day.
|
||||
|
||||
.. figure:: /_static/images/repair-prices-missing-split-adjust.png
|
||||
:alt: MOB.ST: repair missing split adjustment
|
||||
:width: 80%
|
||||
:align: left
|
||||
|
||||
MOB.ST
|
||||
|
||||
.. container:: clearer
|
||||
|
||||
..
|
||||
|
||||
Missing data
|
||||
------------
|
||||
|
||||
If price data is clearly missing or corrupt, then reconstructed using smaller interval e.g. ``1h`` to fix ``1d`` data.
|
||||
|
||||
.. figure:: /_static/images/repair-prices-missing-row.png
|
||||
:alt: 1COV.DE: repair missing row
|
||||
:width: 80%
|
||||
:align: left
|
||||
|
||||
1COV.DE missing row
|
||||
|
||||
.. container:: clearer
|
||||
|
||||
..
|
||||
|
||||
.. figure:: /_static/images/repair-prices-missing-volume-intraday.png
|
||||
:alt: 1COV.DE: repair missing Volume, but intraday price changed
|
||||
:width: 80%
|
||||
:align: left
|
||||
|
||||
1COV.DE missing Volume, but intraday price changed
|
||||
|
||||
.. container:: clearer
|
||||
|
||||
..
|
||||
|
||||
.. figure:: /_static/images/repair-prices-missing-volume-daily.png
|
||||
:alt: 0316.HK: repair missing Volume, but daily price changed
|
||||
:width: 80%
|
||||
:align: left
|
||||
|
||||
0316.HK missing Volume, but daily price changed
|
||||
|
||||
.. container:: clearer
|
||||
|
||||
..
|
||||
|
||||
100x errors
|
||||
-----------
|
||||
|
||||
Sometimes Yahoo mixes up currencies e.g. $/cents or £/pence. So some prices are 100x wrong.
|
||||
Sometimes they are spread randomly through data - these detected with ``scipy`` module.
|
||||
Other times they are in a block, because Yahoo decided one day to permanently switch currency.
|
||||
|
||||
.. figure:: /_static/images/repair-prices-100x.png
|
||||
:alt: AET.L: repair 100x
|
||||
:width: 80%
|
||||
:align: left
|
||||
|
||||
AET.L
|
||||
|
||||
Price reconstruction - algorithm notes
|
||||
--------------------------------------
|
||||
|
||||
Spam minimised by grouping fetches. Tries to be aware of data limits e.g. ``1h`` cannot be fetched beyond 2 years.
|
||||
|
||||
If Yahoo eventually does fix the bad data that required reconstruction, you will see it's slightly different to reconstructed prices and volume often significantly different. Best I can do, and beats missing data.
|
||||
|
||||
Dividend repair (new)
|
||||
=====================
|
||||
|
||||
Fix errors in dividends:
|
||||
|
||||
1. adjustment missing or 100x too small/big for the dividend
|
||||
2. duplicate dividend (within 7 days)
|
||||
3. dividend 100x too big/small for the ex-dividend price drop
|
||||
4. ex-div date wrong (price drop is few days/weeks after)
|
||||
|
||||
Most errors I've seen are on London stock exchange (£/pence mixup), but no exchange is safe.
|
||||
|
||||
IMPORTANT - false positives
|
||||
---------------------------
|
||||
|
||||
Because fixing (3) relies on price action, there is a chance of a "false positive" (FP) - thinking an error exists when data is good.
|
||||
FP rate increases with longer intervals, so only 1d intervals are repaired. If you request repair on multiday intervals (weekly etc), then: 1d is fetched from Yahoo, repaired, then resampled - **this has nice side-effect of solving Yahoo's flawed way of div-adjusting multiday intervals.**
|
||||
|
||||
FP rate on 1d is tiny. They tend to happen with tiny dividends e.g. 0.5%, mistaking normal price volatility for an ex-div drop 100x bigger than the dividend, causing repair of the "too small" dividend (repair logic already tries to account for normal volatility by subtracting median). Either accept the risk, or fetch 6-12 months of prices with at least 2 dividends - then can analyse the dividends together to identify false positives.
|
||||
|
||||
Adjustment missing
|
||||
------------------
|
||||
|
||||
1398.HK
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Dividends
|
||||
2024-07-08 00:00:00+08:00 4.33 4.33 0.335715
|
||||
2024-07-04 00:00:00+08:00 4.83 4.83 0.000000
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# REPAIRED:
|
||||
Close Adj Close Dividends
|
||||
2024-07-08 00:00:00+08:00 4.33 4.330000 0.335715
|
||||
2024-07-04 00:00:00+08:00 4.83 4.494285 0.000000
|
||||
|
||||
Adjustment too small
|
||||
--------------------
|
||||
|
||||
3IN.L
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Dividends
|
||||
2024-06-13 00:00:00+01:00 3.185 3.185000 0.05950
|
||||
2024-06-12 00:00:00+01:00 3.270 3.269405 0.00000
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# REPAIRED:
|
||||
Close Adj Close Dividends
|
||||
2024-06-13 00:00:00+01:00 3.185 3.185000 0.05950
|
||||
2024-06-12 00:00:00+01:00 3.270 3.210500 0.00000
|
||||
|
||||
Duplicate (within 7 days)
|
||||
-------------------------
|
||||
|
||||
ALC.SW
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Dividends
|
||||
2023-05-10 00:00:00+02:00 70.580002 70.352142 0.21
|
||||
2023-05-09 00:00:00+02:00 65.739998 65.318443 0.21
|
||||
2023-05-08 00:00:00+02:00 66.379997 65.745682 0.00
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# REPAIRED:
|
||||
Close Adj Close Dividends
|
||||
2023-05-10 00:00:00+02:00 70.580002 70.352142 0.00
|
||||
2023-05-09 00:00:00+02:00 65.739998 65.527764 0.21
|
||||
2023-05-08 00:00:00+02:00 66.379997 65.956371 0.00
|
||||
|
||||
Dividend too big
|
||||
----------------
|
||||
|
||||
HLCL.L
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Dividends
|
||||
2024-06-27 00:00:00+01:00 2.360 2.3600 1.78
|
||||
2024-06-26 00:00:00+01:00 2.375 2.3572 0.00
|
||||
|
||||
# REPAIRED:
|
||||
Close Adj Close Dividends
|
||||
2024-06-27 00:00:00+01:00 2.360 2.3600 0.0178
|
||||
2024-06-26 00:00:00+01:00 2.375 2.3572 0.0000
|
||||
|
||||
Dividend & adjust too big
|
||||
-------------------------
|
||||
|
||||
LTI.L
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Adj Dividends
|
||||
2024-08-08 00:00:00+01:00 768.0 768.0 1.0000 5150.0
|
||||
2024-08-07 00:00:00+01:00 819.0 -4331.0 -5.2882 0.0
|
||||
Close Adj Close Adj Dividends
|
||||
2024-08-08 00:00:00+01:00 768.0 768.0 1.0000 51.5
|
||||
2024-08-07 00:00:00+01:00 819.0 767.5 0.9371 0.0
|
||||
|
||||
Dividend too small
|
||||
------------------
|
||||
|
||||
BVT.L
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Adj Dividends
|
||||
2022-02-03 00:00:00+00:00 0.7534 0.675197 0.8962 0.00001
|
||||
2022-02-01 00:00:00+00:00 0.7844 0.702970 0.8962 0.00000
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# REPAIRED:
|
||||
Close Adj Close Adj Dividends
|
||||
2022-02-03 00:00:00+00:00 0.7534 0.675197 0.8962 0.001
|
||||
2022-02-01 00:00:00+00:00 0.7844 0.702075 0.8950 0.000
|
||||
|
||||
Adjusted 2x on day before
|
||||
-------------------------
|
||||
|
||||
clue: Close < Low
|
||||
|
||||
2020.OL
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Low Close Adj Close Dividends
|
||||
2023-12-21 00:00:00+01:00 120.199997 121.099998 118.868782 0.18
|
||||
2023-12-20 00:00:00+01:00 122.000000 121.900002 119.477371 0.00
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# REPAIRED:
|
||||
Low Close Adj Close Dividends
|
||||
2023-12-21 00:00:00+01:00 120.199997 121.099998 118.868782 0.18
|
||||
2023-12-20 00:00:00+01:00 122.000000 122.080002 119.654045 0.00
|
||||
|
||||
ex-div date wrong
|
||||
-----------------
|
||||
|
||||
TETY.ST
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# ORIGINAL:
|
||||
Close Adj Close Dividends
|
||||
2022-06-22 00:00:00+02:00 66.699997 60.085415 0.0
|
||||
2022-06-21 00:00:00+02:00 71.599998 64.499489 0.0
|
||||
2022-06-20 00:00:00+02:00 71.800003 64.679657 5.0
|
||||
2022-06-17 00:00:00+02:00 71.000000 59.454838 0.0
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
# REPAIRED:
|
||||
Close Adj Close Dividends
|
||||
2022-06-22 00:00:00+02:00 66.699997 60.085415 5.0
|
||||
2022-06-21 00:00:00+02:00 71.599998 60.007881 0.0
|
||||
2022-06-20 00:00:00+02:00 71.800003 60.175503 0.0
|
||||
2022-06-17 00:00:00+02:00 71.000000 59.505021 0.0
|
||||
@@ -1,11 +0,0 @@
|
||||
************
|
||||
Proxy Server
|
||||
************
|
||||
|
||||
You can download data via a proxy:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
msft = yf.Ticker("MSFT")
|
||||
msft.history(..., proxy="PROXY_SERVER")
|
||||
|
||||
@@ -10,8 +10,8 @@ sys.path.insert(0, os.path.abspath('../..'))
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'yfinance - market data downloader'
|
||||
copyright = '2017-2019 Ran Aroussi'
|
||||
project = 'yfinance / Pythonic access to market data'
|
||||
copyright = '2017-2025 Ran Aroussi'
|
||||
author = 'Ran Aroussi'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
@@ -29,7 +29,8 @@ exclude_patterns = []
|
||||
autoclass_content = 'both'
|
||||
autosummary_generate = True
|
||||
autodoc_default_options = {
|
||||
'exclude-members': '__init__'
|
||||
'exclude-members': '__init__',
|
||||
'members': True,
|
||||
}
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
@@ -39,7 +40,11 @@ html_title = 'yfinance'
|
||||
html_theme = 'pydata_sphinx_theme'
|
||||
html_theme_options = {
|
||||
"github_url": "https://github.com/ranaroussi/yfinance",
|
||||
"navbar_align": "left"
|
||||
"navbar_align": "left",
|
||||
"logo": {
|
||||
"image_light": "_static/logo-light.webp",
|
||||
"image_dark": "_static/logo-dark.webp"
|
||||
}
|
||||
}
|
||||
html_static_path = ['_static']
|
||||
html_css_files = ['yfinance.css']
|
||||
|
||||
90
doc/source/development/code.rst
Normal file
@@ -0,0 +1,90 @@
|
||||
****
|
||||
Code
|
||||
****
|
||||
|
||||
To support rapid development without breaking stable versions, this project uses a two-layer branch model:
|
||||
|
||||
.. image:: assets/branches.png
|
||||
:alt: Branching Model
|
||||
|
||||
`Inspiration <https://miro.medium.com/max/700/1*2YagIpX6LuauC3ASpwHekg.png>`_
|
||||
|
||||
- **dev**: New features and some bug fixes are merged here. This branch allows collective testing, conflict resolution, and further stabilization before merging into the stable branch.
|
||||
- **main**: Stable branch where PIP releases are created.
|
||||
|
||||
By default, branches target **main**, but most contributions should target **dev**.
|
||||
|
||||
**Exceptions**:
|
||||
Direct merges to **main** are allowed if:
|
||||
|
||||
- `yfinance` is massively broken
|
||||
- Part of `yfinance` is broken, and the fix is simple and isolated
|
||||
- Not updating the code (e.g. docs)
|
||||
|
||||
Creating your branch
|
||||
--------------------
|
||||
|
||||
1. Fork the repository on GitHub. If already forked, remember to ``Sync fork``
|
||||
|
||||
2. Clone your forked repository:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/{user}/{repo}.git
|
||||
|
||||
3. Create a new branch for your feature or bug fix, from appropriate base branch:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git checkout {base e.g. dev}
|
||||
git pull
|
||||
git checkout -b {your branch}
|
||||
|
||||
4. Make your changes, commit them, and push your branch to GitHub. To keep the commit history and `network graph <https://github.com/ranaroussi/yfinance/network>`_ compact, give your commits a very short summary then description:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git commit -m "short sentence summary" -m "full commit message"
|
||||
# Long message can be multiple lines (tip: copy-paste)
|
||||
|
||||
6. `Open a pull request on Github <https://github.com/ranaroussi/yfinance/pulls>`_.
|
||||
|
||||
Running a branch
|
||||
----------------
|
||||
|
||||
Please see `this page </development/running>`_.
|
||||
|
||||
Git stuff
|
||||
---------
|
||||
|
||||
- You might be asked to move your branch from ``main`` to ``dev``. This is a ``git rebase``. Remember to update **all** branches involved.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# update all branches:
|
||||
git checkout main
|
||||
git pull
|
||||
git checkout dev
|
||||
git pull
|
||||
# rebase from main to dev:
|
||||
git checkout {your branch}
|
||||
git pull
|
||||
git rebase --onto dev main {your branch}
|
||||
git push --force-with-lease origin {your branch}
|
||||
|
||||
- ``git rebase`` can also be used to update your branch with new commits from base, but without adding a commit to your branch history like git merge does. This keeps history clean and avoids future merge problems.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git checkout {base branch e.g. dev}
|
||||
git pull
|
||||
git checkout {your branch}
|
||||
git rebase {base}
|
||||
git push --force-with-lease origin {your branch}
|
||||
|
||||
- ``git squash`` tiny or negligible commits with meaningful ones, or to combine successive related commits. `git squash guide <https://docs.gitlab.com/ee/topics/git/git_rebase.html#interactive-rebase>`_
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git rebase -i HEAD~2
|
||||
git push --force-with-lease origin {your branch}
|
||||
@@ -1,109 +0,0 @@
|
||||
********************************
|
||||
Contributiong to yfinance
|
||||
********************************
|
||||
|
||||
`yfinance` relies on the community to investigate bugs and contribute code. Here’s how you can help:
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
1. Fork the repository on GitHub.
|
||||
2. Clone your forked repository:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/your-username/yfinance.git
|
||||
|
||||
3. Create a new branch for your feature or bug fix:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
git checkout -b feature-branch-name
|
||||
|
||||
4. Make your changes, commit them, and push your branch to GitHub. To keep the commit history and `network graph <https://github.com/ranaroussi/yfinance/network>`_ compact:
|
||||
|
||||
Use short summaries for commits
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git commit -m "short summary" -m "full commit message"
|
||||
|
||||
**Squash** tiny or negligible commits with meaningful ones.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git rebase -i HEAD~2
|
||||
git push --force-with-lease origin <branch-name>
|
||||
|
||||
5. Open a pull request on the `yfinance` GitHub page.
|
||||
|
||||
For more information, see the `Developer Guide <https://github.com/ranaroussi/yfinance/discussions/1084>`_.
|
||||
|
||||
Branches
|
||||
---------
|
||||
|
||||
To support rapid development without breaking stable versions, this project uses a two-layer branch model:
|
||||
|
||||
.. image:: assets/branches.png
|
||||
:alt: Branching Model
|
||||
|
||||
`Inspiration <https://miro.medium.com/max/700/1*2YagIpX6LuauC3ASpwHekg.png>`_
|
||||
|
||||
- **dev**: New features and some bug fixes are merged here. This branch allows collective testing, conflict resolution, and further stabilization before merging into the stable branch.
|
||||
- **main**: Stable branch where PIP releases are created.
|
||||
|
||||
By default, branches target **main**, but most contributions should target **dev**.
|
||||
|
||||
**Exceptions**:
|
||||
Direct merges to **main** are allowed if:
|
||||
|
||||
- `yfinance` is massively broken
|
||||
- Part of `yfinance` is broken, and the fix is simple and isolated
|
||||
|
||||
Unit Tests
|
||||
----------
|
||||
|
||||
Tests are written using Python’s `unittest` module. Here are some ways to run tests:
|
||||
|
||||
- **Run all price tests**:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m unittest tests.test_prices
|
||||
|
||||
- **Run a subset of price tests**:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m unittest tests.test_prices.TestPriceRepair
|
||||
|
||||
- **Run a specific test**:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m unittest tests.test_prices.TestPriceRepair.test_ticker_missing
|
||||
|
||||
- **Run all tests**:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
python -m unittest discover -s tests
|
||||
|
||||
Rebasing
|
||||
--------------
|
||||
|
||||
If asked to move your branch from **main** to **dev**:
|
||||
|
||||
1. Ensure all relevant branches are pulled.
|
||||
2. Run:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
git checkout <your-branch>
|
||||
git rebase --onto dev main <branch-name>
|
||||
git push --force-with-lease origin <branch-name>
|
||||
|
||||
Running the GitHub Version of yfinance
|
||||
--------------------------------------
|
||||
|
||||
To download and run a GitHub version of `yfinance`, refer to `GitHub discussion <https://github.com/ranaroussi/yfinance/discussions/1080>`_
|
||||
@@ -1,15 +1,15 @@
|
||||
*************************************
|
||||
Contribution to the documentation
|
||||
*************************************
|
||||
*************
|
||||
Documentation
|
||||
*************
|
||||
|
||||
.. contents:: Documentation:
|
||||
:local:
|
||||
|
||||
About documentation
|
||||
------------------------
|
||||
-------------------
|
||||
* yfinance documentation is written in reStructuredText (rst) and built using Sphinx.
|
||||
* The documentation file is in `doc/source/..`.
|
||||
* Most of the notes under API References read from class and methods docstrings. These documentations, found in `doc/source/reference/api` is autogenerated by Sphinx and not included in git.
|
||||
* The documentation file is in ``doc/source/..``.
|
||||
* Most of the notes under API References read from class and methods docstrings. These documentations, found in ``doc/source/reference/api`` is autogenerated by Sphinx and not included in git.
|
||||
|
||||
Building documentation locally
|
||||
-------------------------------
|
||||
@@ -17,30 +17,38 @@ To build the documentation locally, follow these steps:
|
||||
|
||||
1. **Install Required Dependencies**:
|
||||
|
||||
* Make sure `Sphinx` and any other dependencies are installed. If a `requirements.txt` file is available, you can install dependencies by running:
|
||||
|
||||
.. code-block:: console
|
||||
* Make sure ``Sphinx`` and any other dependencies are installed. If a ``requirements.txt`` file is available, you can install dependencies by running:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install -r requirements.txt
|
||||
|
||||
pip install Sphinx==8.0.2 pydata-sphinx-theme==0.15.4 Jinja2==3.1.4 sphinx-copybutton==0.5.2
|
||||
|
||||
|
||||
2. **Build with Sphinx**:
|
||||
|
||||
* After dependencies are installed, use the sphinx-build command to generate HTML documentation.
|
||||
* Go to `doc/` directory Run:
|
||||
* Go to ``doc/`` directory Run:
|
||||
|
||||
.. code-block:: console
|
||||
.. code-block:: bash
|
||||
|
||||
make clean && make html
|
||||
sphinx-build -b html doc/source doc/_build/html
|
||||
|
||||
3. **View Documentation Locally**:
|
||||
|
||||
* Open `doc/build/html/index.html` in the browser to view the generated documentation.
|
||||
.. code-block:: bash
|
||||
|
||||
Building documentation on main
|
||||
-------------------------------
|
||||
The documentation updates are built on merge to `main` branch. This is done via GitHub Actions workflow based on `/yfinance/.github/workflows/deploy_doc.yml`.
|
||||
python -m http.server -d ./doc/_build/html
|
||||
|
||||
1. Reivew the changes locally and push to `dev`.
|
||||
Then open "localhost:8000" in browser
|
||||
|
||||
2. When `dev` gets merged to `main`, GitHub Actions workflow is automated to build documentation.
|
||||
|
||||
Publishing documentation
|
||||
------------------------
|
||||
|
||||
Merge into ``main`` branch triggers auto-generating documentation by action ``.github/workflows/deploy_doc.yml``.
|
||||
This publishes the generated HTML into branch ``documentation``.
|
||||
|
||||
1. Review the changes locally and push to ``dev``.
|
||||
|
||||
2. When ``dev`` gets merged to ``main``, GitHub Actions workflow is automated to build documentation.
|
||||
@@ -2,9 +2,12 @@
|
||||
Development
|
||||
===========
|
||||
|
||||
yfinance relies on the community to investigate bugs and contribute code. Here's how you can help:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
contributing
|
||||
code
|
||||
running
|
||||
documentation
|
||||
reporting_bug
|
||||
testing
|
||||
@@ -1,5 +0,0 @@
|
||||
********************************
|
||||
Reporting a Bug
|
||||
********************************
|
||||
|
||||
Open a new issue on our `GitHub <https://github.com/ranaroussi/yfinance/issues>`_.
|
||||
62
doc/source/development/running.rst
Normal file
@@ -0,0 +1,62 @@
|
||||
Running a branch
|
||||
================
|
||||
|
||||
With PIP
|
||||
--------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install git+https://github.com/{user}/{repo}.git@{branch}
|
||||
|
||||
E.g.:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install git+https://github.com/ranaroussi/yfinance.git@feature/name
|
||||
|
||||
With Git
|
||||
--------
|
||||
|
||||
1: Download from GitHub:
|
||||
|
||||
.. code-block:: bash
|
||||
git clone https://github.com/{user}/{repo}.git
|
||||
pip install -r ./yfinance/requirements.txt
|
||||
|
||||
Or if a specific branch:
|
||||
|
||||
.. code-block:: bash
|
||||
git clone -b {branch} https://github.com/{user}/{repo}.git
|
||||
pip install -r ./yfinance/requirements.txt
|
||||
|
||||
.. NOTE::
|
||||
Only do the next part if you are installing globally
|
||||
|
||||
If you are installing for 1 specific project, then you can skip this step
|
||||
and just `git clone` in the project directory
|
||||
|
||||
2. Add download location to Python search path
|
||||
|
||||
Two different ways, choose one:
|
||||
|
||||
1) Add path to ``PYTHONPATH`` environment variable
|
||||
|
||||
2) Add to top of Python file:
|
||||
.. code-block:: python
|
||||
import sys
|
||||
sys.path.insert(0, "path/to/downloaded/yfinance")
|
||||
|
||||
|
||||
3: Verify
|
||||
|
||||
.. code-block:: python
|
||||
import yfinance
|
||||
print(yfinance)
|
||||
|
||||
Output should be:
|
||||
|
||||
`<module 'yfinance' from 'path/to/downloaded/yfinance/yfinance/__init__.py'>`
|
||||
|
||||
If output looks like this then you did step 2 wrong
|
||||
|
||||
`<module 'yfinance' from '.../lib/python3.10/site-packages/yfinance/__init__.py'>`
|
||||
50
doc/source/development/testing.rst
Normal file
@@ -0,0 +1,50 @@
|
||||
Unit Tests
|
||||
----------
|
||||
|
||||
Tests are written using Python's `unittest` module. Here are some ways to run tests:
|
||||
|
||||
- **Run all price tests**:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m unittest tests.test_prices
|
||||
|
||||
- **Run a subset of price tests**:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m unittest tests.test_prices.TestPriceRepair
|
||||
|
||||
- **Run a specific test**:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m unittest tests.test_prices_repair.TestPriceRepair.test_ticker_missing
|
||||
|
||||
- **General command**:
|
||||
|
||||
..code-block:: bash
|
||||
|
||||
python -m unittest tests.{file}.{class}.{method}
|
||||
|
||||
- **Run all tests**:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
python -m unittest discover -s tests
|
||||
|
||||
.. note::
|
||||
|
||||
The tests are currently failing already
|
||||
|
||||
Standard result:
|
||||
|
||||
**Failures:** 11
|
||||
|
||||
**Errors:** 93
|
||||
|
||||
**Skipped:** 1
|
||||
|
||||
.. seealso::
|
||||
|
||||
See the ` ``unittest`` module <https://docs.python.org/3/library/unittest.html>`_ for more information.
|
||||
23
doc/source/reference/examples/live_async.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import asyncio
|
||||
import yfinance as yf
|
||||
|
||||
# define your message callback
|
||||
def message_handler(message):
|
||||
print("Received message:", message)
|
||||
|
||||
async def main():
|
||||
# =======================
|
||||
# With Context Manager
|
||||
# =======================
|
||||
async with yf.AsyncWebSocket() as ws:
|
||||
await ws.subscribe(["AAPL", "BTC-USD"])
|
||||
await ws.listen()
|
||||
|
||||
# =======================
|
||||
# Without Context Manager
|
||||
# =======================
|
||||
ws = yf.AsyncWebSocket()
|
||||
await ws.subscribe(["AAPL", "BTC-USD"])
|
||||
await ws.listen()
|
||||
|
||||
asyncio.run(main())
|
||||
19
doc/source/reference/examples/live_sync.py
Normal file
@@ -0,0 +1,19 @@
|
||||
import yfinance as yf
|
||||
|
||||
# define your message callback
|
||||
def message_handler(message):
|
||||
print("Received message:", message)
|
||||
|
||||
# =======================
|
||||
# With Context Manager
|
||||
# =======================
|
||||
with yf.WebSocket() as ws:
|
||||
ws.subscribe(["AAPL", "BTC-USD"])
|
||||
ws.listen(message_handler)
|
||||
|
||||
# =======================
|
||||
# Without Context Manager
|
||||
# =======================
|
||||
ws = yf.WebSocket()
|
||||
ws.subscribe(["AAPL", "BTC-USD"])
|
||||
ws.listen(message_handler)
|
||||
33
doc/source/reference/examples/lookup.py
Normal file
@@ -0,0 +1,33 @@
|
||||
import yfinance as yf
|
||||
|
||||
# Get All
|
||||
all = yf.Lookup("AAPL").all
|
||||
all = yf.Lookup("AAPL").get_all(count=100)
|
||||
|
||||
# Get Stocks
|
||||
stock = yf.Lookup("AAPL").stock
|
||||
stock = yf.Lookup("AAPL").get_stock(count=100)
|
||||
|
||||
# Get Mutual Funds
|
||||
mutualfund = yf.Lookup("AAPL").mutualfund
|
||||
mutualfund = yf.Lookup("AAPL").get_mutualfund(count=100)
|
||||
|
||||
# Get ETFs
|
||||
etf = yf.Lookup("AAPL").etf
|
||||
etf = yf.Lookup("AAPL").get_etf(count=100)
|
||||
|
||||
# Get Indices
|
||||
index = yf.Lookup("AAPL").index
|
||||
index = yf.Lookup("AAPL").get_index(count=100)
|
||||
|
||||
# Get Futures
|
||||
future = yf.Lookup("AAPL").future
|
||||
future = yf.Lookup("AAPL").get_future(count=100)
|
||||
|
||||
# Get Currencies
|
||||
currency = yf.Lookup("AAPL").currency
|
||||
currency = yf.Lookup("AAPL").get_currency(count=100)
|
||||
|
||||
# Get Cryptocurrencies
|
||||
cryptocurrency = yf.Lookup("AAPL").cryptocurrency
|
||||
cryptocurrency = yf.Lookup("AAPL").get_cryptocurrency(count=100)
|
||||
@@ -20,3 +20,6 @@ dat.info
|
||||
|
||||
# analysis
|
||||
dat.analyst_price_targets
|
||||
|
||||
# websocket
|
||||
dat.live()
|
||||
|
||||
@@ -5,4 +5,7 @@ tickers = yf.Tickers('msft aapl goog')
|
||||
# access each ticker using (example)
|
||||
tickers.tickers['MSFT'].info
|
||||
tickers.tickers['AAPL'].history(period="1mo")
|
||||
tickers.tickers['GOOG'].actions
|
||||
tickers.tickers['GOOG'].actions
|
||||
|
||||
# websocket
|
||||
tickers.live()
|
||||
|
||||
@@ -15,14 +15,18 @@ The following are the publicly available classes, and functions exposed by the `
|
||||
|
||||
- :attr:`Ticker <yfinance.Ticker>`: Class for accessing single ticker data.
|
||||
- :attr:`Tickers <yfinance.Tickers>`: Class for handling multiple tickers.
|
||||
- :attr:`MarketSummary <yfinance.MarketSummary>`: Class for accessing market summary.
|
||||
- :attr:`Market <yfinance.Market>`: Class for accessing market summary.
|
||||
- :attr:`download <yfinance.download>`: Function to download market data for multiple tickers.
|
||||
- :attr:`Search <yfinance.Search>`: Class for accessing search results.
|
||||
- :attr:`Lookup <yfinance.Lookup>`: Class for looking up tickers.
|
||||
- :class:`WebSocket <yfinance.WebSocket>`: Class for synchronously streaming live market data.
|
||||
- :class:`AsyncWebSocket <yfinance.AsyncWebSocket>`: Class for asynchronously streaming live market data.
|
||||
- :attr:`Sector <yfinance.Sector>`: Domain class for accessing sector information.
|
||||
- :attr:`Industry <yfinance.Industry>`: Domain class for accessing industry information.
|
||||
- :attr:`download <yfinance.download>`: Function to download market data for multiple tickers.
|
||||
- :attr:`EquityOperation <yfinance.EquityOperation>`: Class to build equity market operation.
|
||||
- :attr:`Query <yfinance.Query>`: Class to build query.
|
||||
- :attr:`Screener <yfinance.Screener>`: Class to screen the market using defined query.
|
||||
- :attr:`Market <yfinance.Market>`: Class for accessing market status & summary.
|
||||
- :attr:`EquityQuery <yfinance.EquityQuery>`: Class to build equity query filters.
|
||||
- :attr:`FundQuery <yfinance.FundQuery>`: Class to build fund query filters.
|
||||
- :attr:`screen <yfinance.screen>`: Run equity/fund queries.
|
||||
- :attr:`enable_debug_mode <yfinance.enable_debug_mode>`: Function to enable debug mode for logging.
|
||||
- :attr:`set_tz_cache_location <yfinance.set_tz_cache_location>`: Function to set the timezone cache location.
|
||||
|
||||
@@ -33,10 +37,13 @@ The following are the publicly available classes, and functions exposed by the `
|
||||
|
||||
yfinance.ticker_tickers
|
||||
yfinance.stock
|
||||
yfinance.market
|
||||
yfinance.financials
|
||||
yfinance.analysis
|
||||
yfinance.marketsummary
|
||||
yfinance.market
|
||||
yfinance.search
|
||||
yfinance.lookup
|
||||
yfinance.websocket
|
||||
yfinance.sector_industry
|
||||
yfinance.screener
|
||||
yfinance.functions
|
||||
|
||||
@@ -10,12 +10,16 @@ Financials
|
||||
|
||||
get_income_stmt
|
||||
income_stmt
|
||||
quarterly_income_stmt
|
||||
ttm_income_stmt
|
||||
|
||||
get_balance_sheet
|
||||
balance_sheet
|
||||
|
||||
get_cashflow
|
||||
cashflow
|
||||
quarterly_cashflow
|
||||
ttm_cashflow
|
||||
|
||||
get_earnings
|
||||
earnings
|
||||
|
||||
@@ -1,16 +1,41 @@
|
||||
=====================
|
||||
Market Summary
|
||||
Market
|
||||
=====================
|
||||
|
||||
.. currentmodule:: yfinance
|
||||
|
||||
|
||||
Class
|
||||
------------
|
||||
The `Market` class, allows you to access market data in a Pythonic way.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: api/
|
||||
|
||||
Market
|
||||
|
||||
Market Sample Code
|
||||
--------------------------
|
||||
The `Market` class, allows you to access market summary data in a Pythonic way.
|
||||
------------------
|
||||
|
||||
.. literalinclude:: examples/market.py
|
||||
:language: python
|
||||
:language: python
|
||||
|
||||
|
||||
Markets
|
||||
------------
|
||||
There are 8 different markets available in Yahoo Finance.
|
||||
|
||||
* US
|
||||
* GB
|
||||
|
||||
\
|
||||
|
||||
* ASIA
|
||||
* EUROPE
|
||||
|
||||
\
|
||||
|
||||
* RATES
|
||||
* COMMODITIES
|
||||
* CURRENCIES
|
||||
* CRYPTOCURRENCIES
|
||||
@@ -1,5 +1,5 @@
|
||||
=====================
|
||||
Search & News
|
||||
Search & Lookup
|
||||
=====================
|
||||
|
||||
.. currentmodule:: yfinance
|
||||
@@ -14,9 +14,21 @@ The `Search` module, allows you to access search data in a Pythonic way.
|
||||
|
||||
Search
|
||||
|
||||
Search Sample Code
|
||||
The `Lookup` module, allows you to look up tickers in a Pythonic way.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: api/
|
||||
|
||||
Lookup
|
||||
|
||||
Sample Code
|
||||
------------------
|
||||
The `Search` module, allows you to access search data in a Pythonic way.
|
||||
|
||||
.. literalinclude:: examples/search.py
|
||||
:language: python
|
||||
|
||||
The `Lookup` module, allows you to look up tickers in a Pythonic way.
|
||||
|
||||
.. literalinclude:: examples/lookup.py
|
||||
:language: python
|
||||
|
||||
@@ -20,6 +20,9 @@ Ticker stock methods
|
||||
:meth:`yfinance.scrapers.history.PriceHistory.history`
|
||||
Documentation for history
|
||||
|
||||
:doc:`../advanced/price_repair`
|
||||
Documentation for price repair
|
||||
|
||||
.. autosummary::
|
||||
:toctree: api/
|
||||
:recursive:
|
||||
|
||||
46
doc/source/reference/yfinance.websocket.rst
Normal file
@@ -0,0 +1,46 @@
|
||||
=====================
|
||||
WebSocket
|
||||
=====================
|
||||
|
||||
.. currentmodule:: yfinance
|
||||
|
||||
The `WebSocket` module allows you to stream live price data from Yahoo Finance using both synchronous and asynchronous clients.
|
||||
|
||||
Classes
|
||||
------------
|
||||
|
||||
.. autosummary::
|
||||
:toctree: api/
|
||||
|
||||
WebSocket
|
||||
AsyncWebSocket
|
||||
|
||||
Synchronous WebSocket
|
||||
----------------------
|
||||
|
||||
The `WebSocket` class provides a synchronous interface for subscribing to price updates.
|
||||
|
||||
Sample Code:
|
||||
|
||||
.. literalinclude:: examples/live_sync.py
|
||||
:language: python
|
||||
|
||||
Asynchronous WebSocket
|
||||
-----------------------
|
||||
|
||||
The `AsyncWebSocket` class provides an asynchronous interface for subscribing to price updates.
|
||||
|
||||
Sample Code:
|
||||
|
||||
.. literalinclude:: examples/live_async.py
|
||||
:language: python
|
||||
|
||||
.. note::
|
||||
If you're running asynchronous code in a Jupyter notebook, you may encounter issues with event loops. To resolve this, you need to import and apply `nest_asyncio` to allow nested event loops.
|
||||
|
||||
Add the following code before running asynchronous operations:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import nest_asyncio
|
||||
nest_asyncio.apply()
|
||||
BIN
doc/yfinance-gh-icon-dark.webp
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
doc/yfinance-gh-icon-light.webp
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
doc/yfinance-gh-logo-dark.webp
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
doc/yfinance-gh-logo-light.webp
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
@@ -1,5 +1,5 @@
|
||||
{% set name = "yfinance" %}
|
||||
{% set version = "0.2.52" %}
|
||||
{% set version = "0.2.65" %}
|
||||
|
||||
package:
|
||||
name: "{{ name|lower }}"
|
||||
@@ -26,8 +26,8 @@ requirements:
|
||||
- frozendict >=2.3.4
|
||||
- beautifulsoup4 >=4.11.1
|
||||
- html5lib >=1.1
|
||||
- curl_cffi >=0.7
|
||||
- peewee >=3.16.2
|
||||
# - pycryptodome >=3.6.6
|
||||
- pip
|
||||
- python
|
||||
|
||||
@@ -42,8 +42,8 @@ requirements:
|
||||
- frozendict >=2.3.4
|
||||
- beautifulsoup4 >=4.11.1
|
||||
- html5lib >=1.1
|
||||
- curl_cffi >=0.7
|
||||
- peewee >=3.16.2
|
||||
# - pycryptodome >=3.6.6
|
||||
- python
|
||||
|
||||
test:
|
||||
|
||||
@@ -2,13 +2,14 @@ pandas>=1.3.0
|
||||
numpy>=1.16.5
|
||||
requests>=2.31
|
||||
multitasking>=0.0.7
|
||||
lxml>=4.9.1
|
||||
platformdirs>=2.0.0
|
||||
pytz>=2022.5
|
||||
frozendict>=2.3.4
|
||||
beautifulsoup4>=4.11.1
|
||||
html5lib>=1.1
|
||||
peewee>=3.16.2
|
||||
requests_cache>=1.0
|
||||
requests_ratelimiter>=0.3.1
|
||||
scipy>=1.6.3
|
||||
scipy>=1.6.3
|
||||
curl_cffi>=0.7
|
||||
protobuf>=3.19.0
|
||||
websockets>=13.0
|
||||
|
||||
10
setup.py
@@ -61,13 +61,19 @@ setup(
|
||||
packages=find_packages(exclude=['contrib', 'docs', 'tests', 'examples']),
|
||||
install_requires=['pandas>=1.3.0', 'numpy>=1.16.5',
|
||||
'requests>=2.31', 'multitasking>=0.0.7',
|
||||
'lxml>=4.9.1', 'platformdirs>=2.0.0', 'pytz>=2022.5',
|
||||
'platformdirs>=2.0.0', 'pytz>=2022.5',
|
||||
'frozendict>=2.3.4', 'peewee>=3.16.2',
|
||||
'beautifulsoup4>=4.11.1', 'html5lib>=1.1'],
|
||||
'beautifulsoup4>=4.11.1', 'curl_cffi>=0.7',
|
||||
'protobuf>=3.19.0', 'websockets>=13.0'],
|
||||
extras_require={
|
||||
'nospam': ['requests_cache>=1.0', 'requests_ratelimiter>=0.3.1'],
|
||||
'repair': ['scipy>=1.6.3'],
|
||||
},
|
||||
# Include protobuf files for websocket support
|
||||
package_data={
|
||||
'yfinance': ['pricing.proto', 'pricing_pb2.py'],
|
||||
},
|
||||
include_package_data=True,
|
||||
# Note: Pandas.read_html() needs html5lib & beautifulsoup4
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
|
||||
@@ -5,10 +5,8 @@ import datetime as _dt
|
||||
import sys
|
||||
import os
|
||||
import yfinance
|
||||
from requests import Session
|
||||
from requests_cache import CacheMixin, SQLiteCache
|
||||
from requests_ratelimiter import LimiterMixin, MemoryQueueBucket
|
||||
from pyrate_limiter import Duration, RequestRate, Limiter
|
||||
# from requests_ratelimiter import LimiterSession
|
||||
# from pyrate_limiter import Duration, RequestRate, Limiter
|
||||
|
||||
_parent_dp = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
||||
_src_dp = _parent_dp
|
||||
@@ -27,19 +25,24 @@ if os.path.isdir(testing_cache_dirpath):
|
||||
import shutil
|
||||
shutil.rmtree(testing_cache_dirpath)
|
||||
|
||||
# Since switching to curl_cffi, the requests_ratelimiter|cache won't work.
|
||||
session_gbl = None
|
||||
|
||||
# Setup a session to rate-limit and cache persistently:
|
||||
class CachedLimiterSession(CacheMixin, LimiterMixin, Session):
|
||||
pass
|
||||
history_rate = RequestRate(1, Duration.SECOND*2)
|
||||
limiter = Limiter(history_rate)
|
||||
cache_fp = os.path.join(testing_cache_dirpath, "unittests-cache")
|
||||
session_gbl = CachedLimiterSession(
|
||||
limiter=limiter,
|
||||
bucket_class=MemoryQueueBucket,
|
||||
backend=SQLiteCache(cache_fp, expire_after=_dt.timedelta(hours=1)),
|
||||
)
|
||||
# Use this instead if only want rate-limiting:
|
||||
# from requests_ratelimiter import LimiterSession
|
||||
# # Setup a session to only rate-limit
|
||||
# history_rate = RequestRate(1, Duration.SECOND)
|
||||
# limiter = Limiter(history_rate)
|
||||
# session_gbl = LimiterSession(limiter=limiter)
|
||||
|
||||
# # Use this instead if you also want caching:
|
||||
# from requests_cache import CacheMixin, SQLiteCache
|
||||
# from requests_ratelimiter import LimiterMixin
|
||||
# from requests import Session
|
||||
# from pyrate_limiter import MemoryQueueBucket
|
||||
# class CachedLimiterSession(CacheMixin, LimiterMixin, Session):
|
||||
# pass
|
||||
# cache_fp = os.path.join(testing_cache_dirpath, "unittests-cache")
|
||||
# session_gbl = CachedLimiterSession(
|
||||
# limiter=limiter,
|
||||
# bucket_class=MemoryQueueBucket,
|
||||
# backend=SQLiteCache(cache_fp, expire_after=_dt.timedelta(hours=1)),
|
||||
# )
|
||||
|
||||
@@ -1,725 +0,0 @@
|
||||
Datetime,Open,High,Low,Close,Adj Close,Volume,Dividends,Stock Splits,Repaired?
|
||||
2022-01-04 00:00:00+00:00,29.46,29.98,28.52,28.66,20.53276113953462,169521.0,0.0,0.0,True
|
||||
2022-01-05 00:00:00+00:00,30.0,30.0,28.46,28.900000000000002,20.70470257643437,128698.0,0.0,0.0,True
|
||||
2022-01-06 00:00:00+00:00,28.2,28.560000000000002,27.5,27.82,19.930963478279654,374659.0,0.0,0.0,True
|
||||
2022-01-07 00:00:00+00:00,28.3,28.3,27.400000000000002,27.46,19.67305220029865,80410.0,0.0,0.0,True
|
||||
2022-01-10 00:00:00+00:00,28.16,28.240000000000002,26.2,26.580000000000002,19.042597925349927,135881.0,0.0,0.0,True
|
||||
2022-01-11 00:00:00+00:00,25.92,27.060000000000002,25.92,26.72,19.142895195909453,71414.0,0.0,0.0,True
|
||||
2022-01-12 00:00:00+00:00,26.72,26.96,26.060000000000002,26.8,19.200210178034187,68611.0,0.0,0.0,True
|
||||
2022-01-13 00:00:00+00:00,26.72,27.3239990234375,26.6,27.2,19.486779824446177,155917.0,0.0,0.0,True
|
||||
2022-01-14 00:00:00+00:00,27.52,27.52,26.36,26.560000000000002,19.028270495871666,66402.0,0.0,0.0,True
|
||||
2022-01-17 00:00:00+00:00,27.02,27.22,26.28,27.22,19.50111251813613,60092.0,0.0,0.0,True
|
||||
2022-01-18 00:00:00+00:00,27.66,27.66,26.0,26.86,19.243195975943426,128385.0,0.0,0.0,True
|
||||
2022-01-19 00:00:00+00:00,27.0,27.46,26.7,27.2,19.486779824446177,75141.0,0.0,0.0,True
|
||||
2022-01-20 00:00:00+00:00,26.900000000000002,27.7,26.81172119140625,27.54,19.730365427686156,99304.0,0.0,0.0,True
|
||||
2022-01-21 00:00:00+00:00,27.26,27.88,26.214208984375002,26.38,18.89931310214393,123570.0,0.0,0.0,True
|
||||
2022-01-24 00:00:00+00:00,26.14,26.261599121093752,24.72,24.88,17.824671663887276,148794.0,0.0,0.0,True
|
||||
2022-01-25 00:00:00+00:00,24.92,25.2,24.580000000000002,24.580000000000002,17.609746183815513,94318.0,0.0,0.0,True
|
||||
2022-01-26 00:00:00+00:00,25.52,25.52,24.400000000000002,24.66,17.667057656465794,265198.0,0.0,0.0,True
|
||||
2022-01-27 00:00:00+00:00,24.66,25.12669921875,24.400000000000002,24.82,17.78168762071526,248811.0,0.0,0.0,True
|
||||
2022-01-28 00:00:00+00:00,24.7,24.88,24.1,24.32,17.4234773174375,146209.0,0.0,0.0,True
|
||||
2022-01-31 00:00:00+00:00,25.3,25.46,24.3,25.2,18.05392983764899,495745.0,0.0,0.0,True
|
||||
2022-02-01 00:00:00+00:00,25.580000000000002,26.78,25.580000000000002,26.7,19.128567766431193,426366.0,0.0,0.0,True
|
||||
2022-02-02 00:00:00+00:00,25.5,27.28,25.5,26.38,18.89931310214393,134118.0,0.0,0.0,True
|
||||
2022-02-03 00:00:00+00:00,26.28,26.3639990234375,24.82,24.88,17.824671663887276,168782.0,0.0,0.0,True
|
||||
2022-02-04 00:00:00+00:00,24.6,25.14,24.400000000000002,24.76,17.738701822806014,110543.0,0.0,0.0,True
|
||||
2022-02-07 00:00:00+00:00,25.04,25.04,24.54,24.54,17.581089570121758,163853.0,0.0,0.0,True
|
||||
2022-02-08 00:00:00+00:00,24.64,24.64,23.8,24.12,17.280188984757043,146007.0,0.0,0.0,True
|
||||
2022-02-09 00:00:00+00:00,24.5,24.98,24.3,24.7,17.695716024896768,130747.0,0.0,0.0,True
|
||||
2022-02-10 00:00:00+00:00,24.52,24.7,24.080000000000002,24.46,17.523774587997018,113862.0,0.0,0.0,True
|
||||
2022-02-11 00:00:00+00:00,24.5,24.72,24.1,24.42,17.49511797430327,87108.0,0.0,0.0,True
|
||||
2022-02-14 00:00:00+00:00,24.42,24.42,23.34,23.98,17.179889959460297,79188.0,0.0,0.0,True
|
||||
2022-02-15 00:00:00+00:00,23.86,24.560000000000002,23.54,24.22,17.35183139636004,175846.0,0.0,0.0,True
|
||||
2022-02-16 00:00:00+00:00,24.580000000000002,24.580000000000002,23.76,23.98,17.179889959460297,62392.0,0.0,0.0,True
|
||||
2022-02-17 00:00:00+00:00,24.78,24.78,23.86,23.86,17.09392011837903,111791.0,0.0,0.0,True
|
||||
2022-02-18 00:00:00+00:00,23.84,23.94760009765625,23.36,23.48,16.821676146708075,61467.0,0.0,0.0,True
|
||||
2022-02-21 00:00:00+00:00,23.46,23.64919921875,22.82,23.080000000000002,16.53510474555885,71820.0,0.0,0.0,True
|
||||
2022-02-22 00:00:00+00:00,24.18,24.18,22.54,23.38,16.75003373510507,75721.0,0.0,0.0,True
|
||||
2022-02-23 00:00:00+00:00,23.78,24.04,23.02,23.02,16.492122457124065,122317.0,0.0,0.0,True
|
||||
2022-02-24 00:00:00+00:00,23.3,23.3,21.96,22.52,16.133908644371843,241118.0,0.0,0.0,True
|
||||
2022-02-25 00:00:00+00:00,23.0,23.56,22.66,23.32,16.70704969193306,147148.0,0.0,0.0,True
|
||||
2022-02-28 00:00:00+00:00,22.36,24.14,22.36,24.14,17.29451641423531,226698.0,0.0,0.0,True
|
||||
2022-03-01 00:00:00+00:00,24.080000000000002,24.22,23.5,23.5,16.836007085660796,218356.0,0.0,0.0,True
|
||||
2022-03-02 00:00:00+00:00,23.7,23.900000000000002,23.26,23.62,16.921978681479285,87219.0,0.0,0.0,True
|
||||
2022-03-03 00:00:00+00:00,23.26,23.8,22.14,22.14,15.861666427438118,137377.0,0.0,0.0,True
|
||||
2022-03-04 00:00:00+00:00,22.3,22.92,20.740000000000002,20.740000000000002,14.858670910258917,173972.0,0.0,0.0,True
|
||||
2022-03-07 00:00:00+00:00,20.740000000000002,21.14,19.5,20.3,14.54344201804733,282380.0,0.0,0.0,True
|
||||
2022-03-08 00:00:00+00:00,20.3,20.82,19.52,19.52,13.984631032070219,268763.0,0.0,0.0,True
|
||||
2022-03-09 00:00:00+00:00,20.0,21.02,19.73,21.02,15.059270715589653,624876.0,0.0,0.0,True
|
||||
2022-03-10 00:00:00+00:00,21.22,21.22,20.38,20.44,14.643742798081307,266261.0,0.0,0.0,True
|
||||
2022-03-11 00:00:00+00:00,20.66,21.52,20.46,20.900000000000002,14.97329911977116,139879.0,0.0,0.0,True
|
||||
2022-03-14 00:00:00+00:00,21.5,21.88,21.1,21.580000000000002,15.460468571513879,87051.0,0.0,0.0,True
|
||||
2022-03-15 00:00:00+00:00,20.72,21.48,20.72,20.96,15.016284917680403,86783.0,0.0,0.0,True
|
||||
2022-03-16 00:00:00+00:00,21.580000000000002,22.72,21.36,22.48,16.10525378541532,118783.0,0.0,0.0,True
|
||||
2022-03-17 00:00:00+00:00,21.68,22.7,21.68,22.46,16.090922846462604,86717.0,0.0,0.0,True
|
||||
2022-03-18 00:00:00+00:00,21.76,23.32,21.76,23.18,16.60675066663631,147084.0,0.0,0.0,True
|
||||
2022-03-21 00:00:00+00:00,23.400000000000002,23.400000000000002,22.26,22.62,16.205551055974844,290436.0,0.0,0.0,True
|
||||
2022-03-22 00:00:00+00:00,23.22,23.22,21.94,22.0,15.761365647404139,89172.0,0.0,0.0,True
|
||||
2022-03-23 00:00:00+00:00,21.68,22.7,21.68,22.56,16.162565258065598,83842.0,0.0,0.0,True
|
||||
2022-03-24 00:00:00+00:00,21.42,22.64,21.400000000000002,22.400000000000002,16.047938803290588,121267.0,0.0,0.0,True
|
||||
2022-03-25 00:00:00+00:00,22.5,23.1,21.92,22.66,16.234207669668603,192618.0,0.0,0.0,True
|
||||
2022-03-28 00:00:00+01:00,22.14,23.32,22.14,22.86,16.37749424761182,109333.0,0.0,0.0,True
|
||||
2022-03-29 00:00:00+01:00,23.02,23.511201171875,22.8360009765625,23.38,16.75003373510507,85895.0,0.0,0.0,True
|
||||
2022-03-30 00:00:00+01:00,23.82,25.740000000000002,23.82,25.740000000000002,18.440800264094957,571137.0,0.0,0.0,True
|
||||
2022-03-31 00:00:00+01:00,25.68,26.2,25.0,26.2,18.77035219894174,458165.0,0.0,0.0,True
|
||||
2022-04-01 00:00:00+01:00,26.32,26.34,25.580000000000002,25.580000000000002,18.32617029984549,206616.0,0.0,0.0,True
|
||||
2022-04-04 00:00:00+01:00,26.400000000000002,26.400000000000002,25.2,25.92,18.569757657822695,150039.0,0.0,0.0,True
|
||||
2022-04-05 00:00:00+01:00,25.94,26.92,25.900000000000002,26.46,18.956626329531442,2241719.0,0.0,0.0,True
|
||||
2022-04-06 00:00:00+01:00,26.62,26.98,26.32,26.52,18.99961212744068,178598.0,0.0,0.0,True
|
||||
2022-04-07 00:00:00+01:00,26.86,27.62,26.44,27.18,19.472452394967913,191304.0,0.0,0.0,True
|
||||
2022-04-08 00:00:00+01:00,27.52,27.72489990234375,26.52,26.62,19.071256293780912,131026.0,0.0,0.0,True
|
||||
2022-04-11 00:00:00+01:00,26.560000000000002,26.692480468750002,25.88,26.0,18.6270708852102,106445.0,0.0,0.0,True
|
||||
2022-04-12 00:00:00+01:00,26.0,26.580000000000002,26.0,26.28,18.827668935803704,134222.0,0.0,0.0,True
|
||||
2022-04-13 00:00:00+01:00,26.62,26.62,25.92,26.3,18.8419981200192,151567.0,0.0,0.0,True
|
||||
2022-04-14 00:00:00+01:00,26.240000000000002,26.52,25.79534912109375,26.0,18.6270708852102,203268.0,0.0,0.0,True
|
||||
2022-04-19 00:00:00+01:00,25.8,26.060000000000002,24.96,25.54,18.29751368615174,202763.0,0.0,0.0,True
|
||||
2022-04-20 00:00:00+01:00,25.740000000000002,25.740000000000002,25.12,25.12,17.996616610261484,133972.0,0.0,0.0,True
|
||||
2022-04-21 00:00:00+01:00,25.22,25.62,25.1,25.2,18.05392983764899,134423.0,0.0,0.0,True
|
||||
2022-04-22 00:00:00+01:00,24.62,25.38,24.62,25.02,17.924972443921252,148749.0,0.0,0.0,True
|
||||
2022-04-25 00:00:00+01:00,24.38,24.86,24.18,24.400000000000002,17.480788790087782,283575.0,0.0,0.0,True
|
||||
2022-04-26 00:00:00+01:00,24.3,24.82,24.22,24.3,17.409144623747547,271554.0,0.0,0.0,True
|
||||
2022-04-27 00:00:00+01:00,24.0,24.94,23.2,23.46,16.807348717229807,147954.0,0.0,0.0,True
|
||||
2022-04-28 00:00:00+01:00,23.48,23.90139892578125,23.42,23.76,17.022275952038804,98816.0,0.0,0.0,True
|
||||
2022-04-29 00:00:00+01:00,23.22,24.16,23.2,24.04,17.222875757369536,139578.0,0.0,0.0,True
|
||||
2022-05-03 00:00:00+01:00,23.6,24.3,23.18,23.48,16.821676146708075,181511.0,0.0,0.0,True
|
||||
2022-05-04 00:00:00+01:00,23.16,23.26,22.24698974609375,22.44,16.07659541698434,199215.0,0.0,0.0,True
|
||||
2022-05-05 00:00:00+01:00,23.52,23.52,22.18,22.26,15.947638023256607,468283.0,0.0,0.0,True
|
||||
2022-05-06 00:00:00+01:00,21.900000000000002,22.06,21.5,22.0,15.761365647404139,119246.0,0.0,0.0,True
|
||||
2022-05-09 00:00:00+01:00,21.88,21.89320068359375,20.8,21.14,15.145240556670908,216918.0,0.0,0.0,True
|
||||
2022-05-10 00:00:00+01:00,21.3,22.02,21.14,21.52,15.417482773604641,175912.0,0.0,0.0,True
|
||||
2022-05-11 00:00:00+01:00,22.080000000000002,22.6,21.48,21.92,15.704052420016632,161619.0,0.0,0.0,True
|
||||
2022-05-12 00:00:00+01:00,21.54,22.0,21.0,21.96,15.732709033710387,162789.0,0.0,0.0,True
|
||||
2022-05-13 00:00:00+01:00,22.0,22.580000000000002,21.88,22.400000000000002,16.047938803290588,136027.0,0.0,0.0,True
|
||||
2022-05-16 00:00:00+01:00,22.28,22.32,21.66,21.88,15.675395806322873,169593.0,0.0,0.0,True
|
||||
2022-05-17 00:00:00+01:00,21.94,22.1,21.580000000000002,21.8,15.6180843336726,230442.0,0.0,0.0,True
|
||||
2022-05-18 00:00:00+01:00,22.76,22.76,21.34,21.36,15.302854564092398,218130.0,0.0,0.0,True
|
||||
2022-05-19 00:00:00+01:00,21.56,21.900000000000002,20.82,21.82,15.63241176315086,161985.0,0.0,0.0,True
|
||||
2022-05-20 00:00:00+01:00,21.88,22.5,21.7,21.76,15.589424210504394,108143.0,0.0,0.0,True
|
||||
2022-05-23 00:00:00+01:00,21.7,22.26,21.68,21.84,15.646737437891897,114671.0,0.0,0.0,True
|
||||
2022-05-24 00:00:00+01:00,22.0,22.0,21.22,21.34,15.288527134614132,80311.0,0.0,0.0,True
|
||||
2022-05-25 00:00:00+01:00,21.44,22.240000000000002,21.3510009765625,21.94,15.718381604232118,108379.0,0.0,0.0,True
|
||||
2022-05-26 00:00:00+01:00,22.240000000000002,22.240000000000002,21.66,22.080000000000002,15.818681213374894,54302.0,0.0,0.0,True
|
||||
2022-05-27 00:00:00+01:00,22.14,22.68,22.04,22.5,16.119582880836756,84161.0,0.0,0.0,True
|
||||
2022-05-30 00:00:00+01:00,22.8,23.1,22.5,22.68,16.248539235253762,92952.0,0.0,0.0,True
|
||||
2022-05-31 00:00:00+01:00,22.0,23.56,22.0,23.42,16.778693136745915,260541.0,0.0,0.0,True
|
||||
2022-06-01 00:00:00+01:00,23.52,23.76,22.96,23.48,16.82167858821825,169299.0,0.0,0.0,True
|
||||
2022-06-06 00:00:00+01:00,23.52,23.76,23.080000000000002,23.56,16.878994277092456,62642.0,0.0,0.0,True
|
||||
2022-06-07 00:00:00+01:00,22.62,23.92,22.62,23.8,17.050936082981796,131089.0,0.0,0.0,True
|
||||
2022-06-08 00:00:00+01:00,23.88,24.22,23.88,24.060000000000002,17.237204619117506,144324.0,0.0,0.0,True
|
||||
2022-06-09 00:00:00+01:00,23.72,24.740000000000002,23.48300048828125,24.32,17.423476662408714,197024.0,0.0,0.0,True
|
||||
2022-06-10 00:00:00+01:00,24.18,24.5,23.68,23.900000000000002,17.122578502102364,391211.0,0.0,0.0,True
|
||||
2022-06-13 00:00:00+01:00,23.78,24.0,22.88,23.2,17.789308885513787,389306.0,1.45,0.0,True
|
||||
2022-06-14 00:00:00+01:00,23.18,23.34,22.92,23.04,17.66662428140854,168973.0,0.0,0.0,True
|
||||
2022-06-15 00:00:00+01:00,22.6,23.18,21.580000000000002,22.26,17.068536836395484,159033.0,0.0,0.0,True
|
||||
2022-06-16 00:00:00+01:00,22.54,22.54,21.82,21.92,16.80783017584214,154582.0,0.0,0.0,True
|
||||
2022-06-17 00:00:00+01:00,22.02,22.62,22.0,22.56,17.29857046909282,162701.0,0.0,0.0,True
|
||||
2022-06-20 00:00:00+01:00,22.54,22.7643994140625,22.3,22.46,17.221890714697334,48492.0,0.0,0.0,True
|
||||
2022-06-21 00:00:00+01:00,22.52,23.1,22.34,22.740000000000002,17.436590648711217,131960.0,0.0,0.0,True
|
||||
2022-06-22 00:00:00+01:00,22.94,23.12,22.03,22.96,17.60528197935593,67403.0,0.0,0.0,True
|
||||
2022-06-23 00:00:00+01:00,23.5,23.5,21.88,22.240000000000002,17.053197507222922,191595.0,0.0,0.0,True
|
||||
2022-06-24 00:00:00+01:00,22.8,23.34,22.580000000000002,23.1,17.712632884777715,186503.0,0.0,0.0,True
|
||||
2022-06-27 00:00:00+01:00,23.080000000000002,23.34,22.78,22.900000000000002,17.559273375986756,75108.0,0.0,0.0,True
|
||||
2022-06-28 00:00:00+01:00,22.84,23.14,22.42,22.6,17.32923974328942,95713.0,0.0,0.0,True
|
||||
2022-06-29 00:00:00+01:00,22.44,22.580000000000002,21.76,21.8,16.715816722763208,143179.0,0.0,0.0,True
|
||||
2022-06-30 00:00:00+01:00,21.38,22.0,21.38,21.94,16.823165751355294,143371.0,0.0,0.0,True
|
||||
2022-07-01 00:00:00+01:00,21.0,22.3,21.0,22.14,16.97652150648685,151912.0,0.0,0.0,True
|
||||
2022-07-04 00:00:00+01:00,22.96,23.12,21.76,21.86,16.761825326132374,163031.0,0.0,0.0,True
|
||||
2022-07-05 00:00:00+01:00,21.8,22.26,21.1,21.54,16.516450487432774,87873.0,0.0,0.0,True
|
||||
2022-07-06 00:00:00+01:00,21.8,22.54,21.8,22.5,17.25256374255335,192002.0,0.0,0.0,True
|
||||
2022-07-07 00:00:00+01:00,22.740000000000002,22.86,22.44739990234375,22.68,17.39058392217175,44045.0,0.0,0.0,True
|
||||
2022-07-08 00:00:00+01:00,22.7,23.1,22.38,23.0,17.63595125355253,54169.0,0.0,0.0,True
|
||||
2022-07-11 00:00:00+01:00,23.0,23.240000000000002,22.68,23.02,17.651288705895393,28404.0,0.0,0.0,True
|
||||
2022-07-12 00:00:00+01:00,23.48,23.48,22.38,22.400000000000002,17.175885864987574,58069.0,0.0,0.0,True
|
||||
2022-07-13 00:00:00+01:00,21.98,22.42,21.54,22.2,17.022528233026314,171315.0,0.0,0.0,True
|
||||
2022-07-14 00:00:00+01:00,21.6,22.28739990234375,21.42,21.8,16.715816722763208,69105.0,0.0,0.0,True
|
||||
2022-07-15 00:00:00+01:00,22.240000000000002,22.46,21.42,22.38,17.160548412644715,37962.0,0.0,0.0,True
|
||||
2022-07-18 00:00:00+01:00,22.52,23.26,22.52,23.1,17.712632884777715,57375.0,0.0,0.0,True
|
||||
2022-07-19 00:00:00+01:00,22.86,23.240000000000002,22.86,23.080000000000002,17.697293555605157,111888.0,0.0,0.0,True
|
||||
2022-07-20 00:00:00+01:00,23.32,23.7,23.27,23.64,18.126693423632915,101102.0,0.0,0.0,True
|
||||
2022-07-21 00:00:00+01:00,23.6,24.3,23.52,24.3,18.63276741556704,94675.0,0.0,0.0,True
|
||||
2022-07-22 00:00:00+01:00,24.22,24.66,24.14,24.28,18.617431840053886,106841.0,0.0,0.0,True
|
||||
2022-07-25 00:00:00+01:00,24.26,24.42,23.96,24.04,18.433404933896025,156132.0,0.0,0.0,True
|
||||
2022-07-26 00:00:00+01:00,24.1,24.1,23.56,23.56,18.065351121580292,100895.0,0.0,0.0,True
|
||||
2022-07-27 00:00:00+01:00,23.48,23.94,23.44,23.580000000000002,18.080686697093444,147619.0,0.0,0.0,True
|
||||
2022-07-28 00:00:00+01:00,24.32,24.400000000000002,23.84,24.400000000000002,18.709447169962523,68667.0,0.0,0.0,True
|
||||
2022-07-29 00:00:00+01:00,24.28,25.48,24.26,25.14,19.27686346394928,215529.0,0.0,0.0,True
|
||||
2022-08-01 00:00:00+01:00,26.0,26.0,24.6,24.900000000000002,19.092834680961705,67096.0,0.0,0.0,True
|
||||
2022-08-02 00:00:00+01:00,24.86,24.900000000000002,24.3,24.52,18.801460623041454,44575.0,0.0,0.0,True
|
||||
2022-08-03 00:00:00+01:00,25.400000000000002,27.664499511718752,24.740000000000002,27.0,20.703077617161842,363560.0,0.0,0.0,True
|
||||
2022-08-04 00:00:00+01:00,26.96,27.06300048828125,25.98,26.42,20.258342173620928,390933.0,0.0,0.0,True
|
||||
2022-08-05 00:00:00+01:00,26.28,27.1,26.22,26.54,20.35035562669986,281941.0,0.0,0.0,True
|
||||
2022-08-08 00:00:00+01:00,26.26,26.84,25.740000000000002,26.02,19.95163066335782,119579.0,0.0,0.0,True
|
||||
2022-08-09 00:00:00+01:00,26.0,26.12,25.400000000000002,25.42,19.491561521133452,81157.0,0.0,0.0,True
|
||||
2022-08-10 00:00:00+01:00,26.0,26.361459960937502,24.84,26.240000000000002,20.120323870832234,236333.0,0.0,0.0,True
|
||||
2022-08-11 00:00:00+01:00,26.22,26.52,25.94,26.26,20.135657569515683,202521.0,0.0,0.0,True
|
||||
2022-08-12 00:00:00+01:00,26.740000000000002,26.76,26.12,26.68,20.45770465529195,94373.0,0.0,0.0,True
|
||||
2022-08-15 00:00:00+01:00,26.0,26.92,25.66,26.68,20.45770465529195,130154.0,0.0,0.0,True
|
||||
2022-08-16 00:00:00+01:00,26.1,26.86,25.34,25.580000000000002,19.6142480020684,220905.0,0.0,0.0,True
|
||||
2022-08-17 00:00:00+01:00,25.66,26.2,25.32,25.740000000000002,19.73693072934394,194549.0,0.0,0.0,True
|
||||
2022-08-18 00:00:00+01:00,25.740000000000002,25.8,25.42,25.8,19.782937455883403,73907.0,0.0,0.0,True
|
||||
2022-08-19 00:00:00+01:00,25.64,25.7,24.38,24.38,18.694109717619664,161331.0,0.0,0.0,True
|
||||
2022-08-22 00:00:00+01:00,24.2,24.42,23.84,24.14,18.510080934632093,309805.0,0.0,0.0,True
|
||||
2022-08-23 00:00:00+01:00,24.2,24.2,23.34,23.42,17.9580002161585,169026.0,0.0,0.0,True
|
||||
2022-08-24 00:00:00+01:00,24.44,24.44,23.240000000000002,24.080000000000002,18.464076084922333,213735.0,0.0,0.0,True
|
||||
2022-08-25 00:00:00+01:00,24.34,24.76,24.14,24.560000000000002,18.832129897238065,103565.0,0.0,0.0,True
|
||||
2022-08-26 00:00:00+01:00,24.68,25.84,24.418798828125002,24.48,18.770789472015146,111767.0,0.0,0.0,True
|
||||
2022-08-30 00:00:00+01:00,25.0,25.32,24.28,24.64,18.893472199290684,114667.0,0.0,0.0,True
|
||||
2022-08-31 00:00:00+01:00,24.3,25.14,24.26,24.86,19.062165406765097,159278.0,0.0,0.0,True
|
||||
2022-09-01 00:00:00+01:00,24.84,24.84,23.28,23.5,18.019344395040825,75741.0,0.0,0.0,True
|
||||
2022-09-02 00:00:00+01:00,23.8,23.900000000000002,23.32,23.86,18.29538663110733,161878.0,0.0,0.0,True
|
||||
2022-09-05 00:00:00+01:00,23.54,24.04,23.19093994140625,23.5,18.019344395040825,89772.0,0.0,0.0,True
|
||||
2022-09-06 00:00:00+01:00,23.54,24.02,23.31,23.580000000000002,18.080686697093444,71477.0,0.0,0.0,True
|
||||
2022-09-07 00:00:00+01:00,23.0,23.72,23.0,23.48,18.004006942697963,97993.0,0.0,0.0,True
|
||||
2022-09-08 00:00:00+01:00,23.400000000000002,23.86,23.12,23.86,18.29538663110733,192900.0,0.0,0.0,True
|
||||
2022-09-09 00:00:00+01:00,23.7,24.240000000000002,23.67845947265625,24.16,18.52542026380466,59221.0,0.0,0.0,True
|
||||
2022-09-12 00:00:00+01:00,24.400000000000002,24.400000000000002,23.82,24.04,18.433404933896025,76307.0,0.0,0.0,True
|
||||
2022-09-13 00:00:00+01:00,24.0,24.76,23.66,23.66,18.142027122316367,155869.0,0.0,0.0,True
|
||||
2022-09-14 00:00:00+01:00,23.66,24.34,23.54,23.84,18.280047301934765,120233.0,0.0,0.0,True
|
||||
2022-09-15 00:00:00+01:00,23.22,23.88,23.18,23.34,17.896657914105877,297665.0,0.0,0.0,True
|
||||
2022-09-16 00:00:00+01:00,23.26,23.32,22.900000000000002,22.92,17.574610828329615,144960.0,0.0,0.0,True
|
||||
2022-09-20 00:00:00+01:00,22.94,24.04,22.6,23.5,18.019344395040825,317042.0,0.0,0.0,True
|
||||
2022-09-21 00:00:00+01:00,23.84,24.36,21.86,23.12,17.72796658346117,273104.0,0.0,0.0,True
|
||||
2022-09-22 00:00:00+01:00,23.02,23.46,22.8,23.240000000000002,17.819981913369805,330760.0,0.0,0.0,True
|
||||
2022-09-23 00:00:00+01:00,23.02,23.14,21.900000000000002,22.56,17.29857046909282,152226.0,0.0,0.0,True
|
||||
2022-09-26 00:00:00+01:00,22.1,22.98,22.1,22.68,17.39058392217175,160292.0,0.0,0.0,True
|
||||
2022-09-27 00:00:00+01:00,22.92,23.52,22.82,22.82,17.497931073934133,170562.0,0.0,0.0,True
|
||||
2022-09-28 00:00:00+01:00,22.1,23.06,21.98,22.86,17.528604101790147,115333.0,0.0,0.0,True
|
||||
2022-09-29 00:00:00+01:00,22.84,22.900000000000002,22.04,22.36,17.14521283713156,131444.0,0.0,0.0,True
|
||||
2022-09-30 00:00:00+01:00,22.7,23.18,22.0,22.98,17.62061755486908,721076.0,0.0,0.0,True
|
||||
2022-10-03 00:00:00+01:00,22.0,23.740000000000002,22.0,23.6,18.0960203957769,411048.0,0.0,0.0,True
|
||||
2022-10-04 00:00:00+01:00,23.14,24.82,23.14,24.48,18.770789472015146,359955.0,0.0,0.0,True
|
||||
2022-10-05 00:00:00+01:00,24.6,24.6,23.38,23.66,18.142027122316367,787207.0,0.0,0.0,True
|
||||
2022-10-06 00:00:00+01:00,23.3,24.36,23.3,24.16,19.148596560732347,179826.0,0.77,0.0,True
|
||||
2022-10-07 00:00:00+01:00,24.32,24.32,23.12,23.28,18.451130936862427,182711.0,0.0,0.0,True
|
||||
2022-10-10 00:00:00+01:00,23.0,23.28,22.240000000000002,22.44,17.78536759068367,138462.0,0.0,0.0,True
|
||||
2022-10-11 00:00:00+01:00,22.38,22.72,22.1,22.18,17.5792979373585,148515.0,0.0,0.0,True
|
||||
2022-10-12 00:00:00+01:00,23.12,23.12,21.88,22.16,17.563445828846387,162450.0,0.0,0.0,True
|
||||
2022-10-13 00:00:00+01:00,22.740000000000002,22.740000000000002,21.12,21.900000000000002,17.357378114854292,326778.0,0.0,0.0,True
|
||||
2022-10-14 00:00:00+01:00,22.0,22.76,21.82,22.5,17.83292197688693,161983.0,0.0,0.0,True
|
||||
2022-10-17 00:00:00+01:00,22.86,23.01260009765625,22.2,22.94,18.18165478882189,116551.0,0.0,0.0,True
|
||||
2022-10-18 00:00:00+01:00,22.26,23.38,22.26,23.12,18.32431794743168,141461.0,0.0,0.0,True
|
||||
2022-10-19 00:00:00+01:00,23.0,23.16,22.240000000000002,22.36,17.72196109596829,104562.0,0.0,0.0,True
|
||||
2022-10-20 00:00:00+01:00,22.38,22.72,21.82,22.5,17.83292197688693,152158.0,0.0,0.0,True
|
||||
2022-10-21 00:00:00+01:00,22.5,23.1,22.28,23.0,18.229207235692083,104972.0,0.0,0.0,True
|
||||
2022-10-24 00:00:00+01:00,23.02,23.900000000000002,23.0,23.38,18.53038566142378,159898.0,0.0,0.0,True
|
||||
2022-10-25 00:00:00+01:00,23.72,24.46,23.42,24.16,19.148596560732347,85381.0,0.0,0.0,True
|
||||
2022-10-26 00:00:00+01:00,24.16,24.2,23.66,24.14,19.132742512887166,117490.0,0.0,0.0,True
|
||||
2022-10-27 00:00:00+01:00,24.080000000000002,24.54,23.88,24.34,19.291259719342143,238792.0,0.0,0.0,True
|
||||
2022-10-28 00:00:00+01:00,24.1,24.22,23.719599609375,24.080000000000002,19.085190066016974,122712.0,0.0,0.0,True
|
||||
2022-10-31 00:00:00+00:00,24.26,24.46,23.66,24.1,19.101040235196017,102273.0,0.0,0.0,True
|
||||
2022-11-01 00:00:00+00:00,24.5,24.94,24.02,24.22,19.19614900760254,72028.0,0.0,0.0,True
|
||||
2022-11-02 00:00:00+00:00,24.1,25.0,23.92,24.64,19.52902971102539,145464.0,0.0,0.0,True
|
||||
2022-11-03 00:00:00+00:00,24.28,24.72,23.88,24.04,19.053485848992747,73546.0,0.0,0.0,True
|
||||
2022-11-04 00:00:00+00:00,24.240000000000002,25.080000000000002,23.60639892578125,24.28,19.24370339380581,69077.0,0.0,0.0,True
|
||||
2022-11-07 00:00:00+00:00,24.22,25.080000000000002,24.02,24.900000000000002,19.735099364350557,124283.0,0.0,0.0,True
|
||||
2022-11-08 00:00:00+00:00,24.580000000000002,25.22,24.580000000000002,25.22,19.988723403878986,153287.0,0.0,0.0,True
|
||||
2022-11-09 00:00:00+00:00,24.98,25.22,24.88,24.98,19.798505859065934,100019.0,0.0,0.0,True
|
||||
2022-11-10 00:00:00+00:00,24.82,26.54,24.64,26.2,20.76544763097639,132777.0,0.0,0.0,True
|
||||
2022-11-11 00:00:00+00:00,26.36,26.86,26.16,26.580000000000002,21.066624117375014,219220.0,0.0,0.0,True
|
||||
2022-11-14 00:00:00+00:00,26.3,27.1,26.26,26.96,21.36780254310671,128692.0,0.0,0.0,True
|
||||
2022-11-15 00:00:00+00:00,26.48,27.16,26.14,26.92,21.336100265415556,186824.0,0.0,0.0,True
|
||||
2022-11-16 00:00:00+00:00,27.02,27.04,26.38,26.52,21.01906973117175,107714.0,0.0,0.0,True
|
||||
2022-11-17 00:00:00+00:00,26.76,26.76,25.8,26.7,21.16173482911461,111413.0,0.0,0.0,True
|
||||
2022-11-18 00:00:00+00:00,26.88,27.1,26.32,27.1,21.47876342402535,127583.0,0.0,0.0,True
|
||||
2022-11-21 00:00:00+00:00,27.96,29.15199951171875,27.43699951171875,27.740000000000002,21.986009563749136,517109.0,0.0,0.0,True
|
||||
2022-11-22 00:00:00+00:00,28.0,28.0,26.86,27.66,21.922605008366833,209083.0,0.0,0.0,True
|
||||
2022-11-23 00:00:00+00:00,27.6,28.34,27.5,28.34,22.461555365114847,458322.0,0.0,0.0,True
|
||||
2022-11-24 00:00:00+00:00,29.0,29.26,27.6,28.8,22.826138346228845,189652.0,0.0,0.0,True
|
||||
2022-11-25 00:00:00+00:00,28.400000000000002,29.03300048828125,28.400000000000002,28.900000000000002,22.905396949456335,146017.0,0.0,0.0,True
|
||||
2022-11-28 00:00:00+00:00,28.7,29.1,28.0,29.1,23.063912216578238,255817.0,0.0,0.0,True
|
||||
2022-11-29 00:00:00+00:00,29.080000000000002,29.14,28.8,28.900000000000002,22.905396949456335,204232.0,0.0,0.0,True
|
||||
2022-11-30 00:00:00+00:00,28.76,29.62,28.76,29.5,23.380940811488976,538520.0,0.0,0.0,True
|
||||
2022-12-01 00:00:00+00:00,29.68,29.900000000000002,29.060000000000002,29.76,23.58701240414721,188618.0,0.0,0.0,True
|
||||
2022-12-02 00:00:00+00:00,29.88,30.560000000000002,29.3,29.48,23.365090642309934,384388.0,0.0,0.0,True
|
||||
2022-12-05 00:00:00+00:00,29.36,29.92,28.26,28.28,22.414000978911588,225089.0,0.0,0.0,True
|
||||
2022-12-06 00:00:00+00:00,28.1,28.48,27.78,27.94,22.144526770204113,320011.0,0.0,0.0,True
|
||||
2022-12-07 00:00:00+00:00,27.92,28.2,27.64,27.94,22.144526770204113,341034.0,0.0,0.0,True
|
||||
2022-12-08 00:00:00+00:00,27.78,28.080000000000002,27.72,27.92,22.128676601025074,219670.0,0.0,0.0,True
|
||||
2022-12-09 00:00:00+00:00,27.400000000000002,28.0,27.400000000000002,28.0,22.19208115640738,138547.0,0.0,0.0,True
|
||||
2022-12-12 00:00:00+00:00,28.400000000000002,28.76300048828125,27.72,28.240000000000002,22.38229870122043,128168.0,0.0,0.0,True
|
||||
2022-12-13 00:00:00+00:00,28.34,29.1,27.86,28.38,22.49325958213907,263580.0,0.0,0.0,True
|
||||
2022-12-14 00:00:00+00:00,28.0,28.36,27.86,28.22,22.36644659270832,62627.0,0.0,0.0,True
|
||||
2022-12-15 00:00:00+00:00,27.900000000000002,28.18,27.54,27.54,21.827496235960307,256065.0,0.0,0.0,True
|
||||
2022-12-16 00:00:00+00:00,27.5,27.96,27.080000000000002,27.400000000000002,21.71653729437474,147966.0,0.0,0.0,True
|
||||
2022-12-19 00:00:00+00:00,27.52,27.9739990234375,27.38,27.52,21.811644127448197,62241.0,0.0,0.0,True
|
||||
2022-12-20 00:00:00+00:00,27.5,27.62,26.8,27.38,21.700685185862625,116737.0,0.0,0.0,True
|
||||
2022-12-21 00:00:00+00:00,27.64,28.1,27.24030029296875,27.86,22.08112027548874,47330.0,0.0,0.0,True
|
||||
2022-12-22 00:00:00+00:00,27.86,28.26,27.3,27.48,21.779943789090108,59975.0,0.0,0.0,True
|
||||
2022-12-23 00:00:00+00:00,28.26,28.26,27.240000000000002,27.46,21.764091680578,37424.0,0.0,0.0,True
|
||||
2022-12-28 00:00:00+00:00,27.44,27.7,27.22,27.42,21.732387463553778,39217.0,0.0,0.0,True
|
||||
2022-12-29 00:00:00+00:00,27.04,27.66,27.02,27.62,21.890902730675684,96876.0,0.0,0.0,True
|
||||
2022-12-30 00:00:00+00:00,26.96,27.66,26.96,27.240000000000002,21.589724304943985,23796.0,0.0,0.0,True
|
||||
2023-01-03 00:00:00+00:00,27.2,28.22,26.64,27.66,21.922605008366833,68033.0,0.0,0.0,True
|
||||
2023-01-04 00:00:00+00:00,27.54,27.98,27.1572998046875,27.88,22.096972384000846,68241.0,0.0,0.0,True
|
||||
2023-01-05 00:00:00+00:00,27.76,28.3,27.562900390625,28.04,22.22378343409853,99643.0,0.0,0.0,True
|
||||
2023-01-06 00:00:00+00:00,27.68,28.72,27.68,28.6,22.667626957773088,132308.0,0.0,0.0,True
|
||||
2023-01-09 00:00:00+00:00,27.0,28.72,26.529279785156252,28.0,22.19208115640738,144894.0,0.0,0.0,True
|
||||
2023-01-10 00:00:00+00:00,29.0,29.0,27.42,27.560000000000002,21.843346405139346,108914.0,0.0,0.0,True
|
||||
2023-01-11 00:00:00+00:00,28.8,28.8,27.36,28.32,22.445705195935805,117605.0,0.0,0.0,True
|
||||
2023-01-12 00:00:00+00:00,28.0,28.16,26.67,26.98,21.38365271228575,394851.0,0.0,0.0,True
|
||||
2023-01-13 00:00:00+00:00,26.76,27.0839990234375,25.400000000000002,25.6,20.28990182961068,356966.0,0.0,0.0,True
|
||||
2023-01-16 00:00:00+00:00,25.0,26.080000000000002,24.86,25.18,19.95702112618783,336471.0,0.0,0.0,True
|
||||
2023-01-17 00:00:00+00:00,25.22,25.400000000000002,24.92,25.3,20.05212795926129,221386.0,0.0,0.0,True
|
||||
2023-01-18 00:00:00+00:00,25.66,26.78,25.37659912109375,26.240000000000002,20.79715184800061,1025972.0,0.0,0.0,True
|
||||
2023-01-19 00:00:00+00:00,27.0,27.0,25.98,26.62,21.098328334399234,102617.0,0.0,0.0,True
|
||||
2023-01-20 00:00:00+00:00,26.72,27.0,26.34,26.44,20.955663236456374,192758.0,0.0,0.0,True
|
||||
2023-01-23 00:00:00+00:00,26.48,26.650000000000002,25.86,26.12,20.702041136261013,159375.0,0.0,0.0,True
|
||||
2023-01-24 00:00:00+00:00,26.3,26.44,25.88,26.060000000000002,20.654486750057753,285494.0,0.0,0.0,True
|
||||
2023-01-25 00:00:00+00:00,26.5,28.04,26.18,27.740000000000002,21.986009563749136,379047.0,0.0,0.0,True
|
||||
2023-01-26 00:00:00+00:00,27.86,28.26,27.66,27.740000000000002,21.986009563749136,234863.0,0.0,0.0,True
|
||||
2023-01-27 00:00:00+00:00,27.900000000000002,28.48,27.44,28.44,22.540812029009263,96625.0,0.0,0.0,True
|
||||
2023-01-30 00:00:00+00:00,28.14,28.68,27.88,28.16,22.318892206505055,169732.0,0.0,0.0,True
|
||||
2023-01-31 00:00:00+00:00,28.060000000000002,28.400000000000002,27.84,28.400000000000002,22.509109751318114,250688.0,0.0,0.0,True
|
||||
2023-02-01 00:00:00+00:00,28.2,28.72,27.400000000000002,28.34,22.461555365114847,97416.0,0.0,0.0,True
|
||||
2023-02-02 00:00:00+00:00,28.68,29.560000000000002,28.1,29.2,23.143168880472654,245261.0,0.0,0.0,True
|
||||
2023-02-03 00:00:00+00:00,29.66,29.7,28.8,29.28,23.20657343585496,211695.0,0.0,0.0,True
|
||||
2023-02-06 00:00:00+00:00,29.02,29.48,28.92597900390625,29.04,23.016357830374975,78978.0,0.0,0.0,True
|
||||
2023-02-07 00:00:00+00:00,28.2,28.98,27.7,28.26,22.39814887039947,327488.0,0.0,0.0,True
|
||||
2023-02-08 00:00:00+00:00,28.7,28.7,28.0,28.36,22.477405534293887,88715.0,0.0,0.0,True
|
||||
2023-02-09 00:00:00+00:00,29.0,29.0,28.44,28.7,22.74688168233443,113023.0,0.0,0.0,True
|
||||
2023-02-10 00:00:00+00:00,28.8,28.89,28.02,28.02,22.20793326491949,169490.0,0.0,0.0,True
|
||||
2023-02-13 00:00:00+00:00,27.900000000000002,28.38,27.36,28.38,22.49325958213907,140602.0,0.0,0.0,True
|
||||
2023-02-14 00:00:00+00:00,27.060000000000002,28.560000000000002,27.060000000000002,28.0,22.19208115640738,107333.0,0.0,0.0,True
|
||||
2023-02-15 00:00:00+00:00,28.18,28.900000000000002,27.724599609375,28.84,22.85784256325307,129853.0,0.0,0.0,True
|
||||
2023-02-16 00:00:00+00:00,27.3,29.240000000000002,27.3,29.12,23.07976432509035,63977.0,0.0,0.0,True
|
||||
2023-02-17 00:00:00+00:00,29.96,29.96,28.5,28.5,22.588368354545597,75842.0,0.0,0.0,True
|
||||
2023-02-20 00:00:00+00:00,28.400000000000002,28.92,28.3,28.900000000000002,22.905396949456335,44533.0,0.0,0.0,True
|
||||
2023-02-21 00:00:00+00:00,28.580000000000002,29.14,28.580000000000002,28.8,22.826138346228845,176561.0,0.0,0.0,True
|
||||
2023-02-22 00:00:00+00:00,28.900000000000002,28.900000000000002,28.48,28.76,22.794438007870767,146264.0,0.0,0.0,True
|
||||
2023-02-23 00:00:00+00:00,28.82,29.34,28.66,28.88,22.88954484094422,86655.0,0.0,0.0,True
|
||||
2023-02-24 00:00:00+00:00,28.98,28.98,28.240000000000002,28.42,22.524961859830224,69783.0,0.0,0.0,True
|
||||
2023-02-27 00:00:00+00:00,28.68,29.060000000000002,28.1,28.84,22.85784256325307,78772.0,0.0,0.0,True
|
||||
2023-02-28 00:00:00+00:00,28.62,29.1,28.580000000000002,28.92,22.921249057968446,386853.0,0.0,0.0,True
|
||||
2023-03-01 00:00:00+00:00,28.92,29.72,28.86,29.36,23.269979930570333,106416.0,0.0,0.0,True
|
||||
2023-03-02 00:00:00+00:00,29.8,29.82,28.92,29.62,23.47605152322857,60874.0,0.0,0.0,True
|
||||
2023-03-03 00:00:00+00:00,29.8,29.92,29.22,29.44,23.33338836461878,59389.0,0.0,0.0,True
|
||||
2023-03-06 00:00:00+00:00,29.46,29.54,29.02,29.240000000000002,23.174873097496874,68220.0,0.0,0.0,True
|
||||
2023-03-07 00:00:00+00:00,28.5,29.6,28.5,29.400000000000002,23.301684147594557,69588.0,0.0,0.0,True
|
||||
2023-03-08 00:00:00+00:00,28.92,29.900000000000002,28.68280029296875,29.64,23.491901692407613,57394.0,0.0,0.0,True
|
||||
2023-03-09 00:00:00+00:00,29.400000000000002,30.0,29.283999023437502,29.92,23.713823454244892,85081.0,0.0,0.0,True
|
||||
2023-03-10 00:00:00+00:00,30.0,30.0,29.0,29.560000000000002,23.428497137025307,121079.0,0.0,0.0,True
|
||||
2023-03-13 00:00:00+00:00,29.26,29.48,28.48,28.48,22.572516246033487,451156.0,0.0,0.0,True
|
||||
2023-03-14 00:00:00+00:00,28.5,29.02,28.28,29.02,23.000505721862865,173562.0,0.0,0.0,True
|
||||
2023-03-15 00:00:00+00:00,28.900000000000002,28.9418505859375,25.46,26.46,20.97151728430156,646146.0,0.0,0.0,True
|
||||
2023-03-16 00:00:00+00:00,26.14,26.88,26.14,26.48,20.987367453480598,240692.0,0.0,0.0,True
|
||||
2023-03-17 00:00:00+00:00,26.72,27.580000000000002,26.42,26.42,20.93981306727734,145813.0,0.0,0.0,True
|
||||
2023-03-20 00:00:00+00:00,26.02,27.28,25.82,26.88,21.304397987724403,156224.0,0.0,0.0,True
|
||||
2023-03-21 00:00:00+00:00,27.12,27.26,26.6,27.2,21.55802008791976,101085.0,0.0,0.0,True
|
||||
2023-03-22 00:00:00+00:00,27.04,27.28,26.68,27.060000000000002,21.44705920700112,61646.0,0.0,0.0,True
|
||||
2023-03-23 00:00:00+00:00,27.46,27.84,27.0,27.76,22.001863611594324,238904.0,0.0,0.0,True
|
||||
2023-03-24 00:00:00+00:00,27.66,27.8639990234375,27.18,27.7,21.954309225391057,151064.0,0.0,0.0,True
|
||||
2023-03-27 00:00:00+01:00,27.98,28.14,27.0,27.060000000000002,21.44705920700112,242115.0,0.0,0.0,True
|
||||
2023-03-28 00:00:00+01:00,27.12,27.12,26.34,26.6,21.082476225887127,162045.0,0.0,0.0,True
|
||||
2023-03-29 00:00:00+01:00,26.64,27.46,26.38,27.240000000000002,21.589724304943985,219929.0,0.0,0.0,True
|
||||
2023-03-30 00:00:00+01:00,27.76,29.080000000000002,27.650000000000002,28.080000000000002,22.255487651122753,285091.0,0.0,0.0,True
|
||||
2023-03-31 00:00:00+01:00,28.1,28.14,27.400000000000002,27.580000000000002,21.85919851365146,143041.0,0.0,0.0,True
|
||||
2023-04-03 00:00:00+01:00,27.580000000000002,27.580000000000002,27.14,27.26,21.6055764134561,100038.0,0.0,0.0,True
|
||||
2023-04-04 00:00:00+01:00,27.14,27.5535400390625,27.04,27.14,21.5104657017165,89315.0,0.0,0.0,True
|
||||
2023-04-05 00:00:00+01:00,27.6,27.8,25.48,25.5,20.21064516571627,174325.0,0.0,0.0,True
|
||||
2023-04-06 00:00:00+01:00,25.6,26.03199951171875,25.46,26.0,20.606932363854487,163437.0,0.0,0.0,True
|
||||
2023-04-11 00:00:00+01:00,26.0,26.580000000000002,25.86,26.22,20.781297800155432,148621.0,0.0,0.0,True
|
||||
2023-04-12 00:00:00+01:00,26.68,27.0,26.02,26.64,21.114180442911348,118071.0,0.0,0.0,True
|
||||
2023-04-13 00:00:00+01:00,26.96,27.400000000000002,26.68,27.18,21.542169918740722,338659.0,0.0,0.0,True
|
||||
2023-04-14 00:00:00+01:00,27.5,27.86,26.72,26.72,21.177584998293653,188709.0,0.0,0.0,True
|
||||
2023-04-17 00:00:00+01:00,26.78,27.060000000000002,26.0356005859375,26.98,21.38365271228575,260010.0,0.0,0.0,True
|
||||
2023-04-18 00:00:00+01:00,28.0,28.0,26.86,27.2,21.55802008791976,110566.0,0.0,0.0,True
|
||||
2023-04-19 00:00:00+01:00,26.8,27.38,26.72,27.240000000000002,21.589724304943985,238055.0,0.0,0.0,True
|
||||
2023-04-20 00:00:00+01:00,27.78,27.78,26.66,26.66,21.130030612090387,136925.0,0.0,0.0,True
|
||||
2023-04-21 00:00:00+01:00,26.5,27.400000000000002,26.48,27.02,21.415356929309976,102818.0,0.0,0.0,True
|
||||
2023-04-24 00:00:00+01:00,26.400000000000002,27.36,26.400000000000002,27.0,21.399506760130933,53770.0,0.0,0.0,True
|
||||
2023-04-25 00:00:00+01:00,26.78,27.34,26.7,26.96,21.36780254310671,584252.0,0.0,0.0,True
|
||||
2023-04-26 00:00:00+01:00,26.78,26.82,26.32,26.64,21.114180442911348,82215.0,0.0,0.0,True
|
||||
2023-04-27 00:00:00+01:00,26.14,26.78,26.14,26.76,21.209289215317877,72994.0,0.0,0.0,True
|
||||
2023-04-28 00:00:00+01:00,27.18,27.18,26.62,27.0,21.399506760130933,63114.0,0.0,0.0,True
|
||||
2023-05-02 00:00:00+01:00,26.400000000000002,27.095419921875,26.34,26.34,20.87640657256196,142978.0,0.0,0.0,True
|
||||
2023-05-03 00:00:00+01:00,26.42,26.5,24.96,25.1,19.893616570805527,350646.0,0.0,0.0,True
|
||||
2023-05-04 00:00:00+01:00,25.0,25.080000000000002,22.68,22.68,17.975585135496722,1493890.0,0.0,0.0,True
|
||||
2023-05-05 00:00:00+01:00,22.6,22.7,21.92,22.0,17.43663477874871,582476.0,0.0,0.0,True
|
||||
2023-05-09 00:00:00+01:00,22.5,22.84,21.75010009765625,22.5,17.83292197688693,529565.0,0.0,0.0,True
|
||||
2023-05-10 00:00:00+01:00,22.5,22.8,21.78,21.8,17.27811951162681,315844.0,0.0,0.0,True
|
||||
2023-05-11 00:00:00+01:00,21.7,23.38,21.7,23.06,18.276763561228417,489035.0,0.0,0.0,True
|
||||
2023-05-12 00:00:00+01:00,23.34,23.38,22.72,23.38,18.53038566142378,283610.0,0.0,0.0,True
|
||||
2023-05-15 00:00:00+01:00,23.04,23.62,23.04,23.5,18.625496373163376,388932.0,0.0,0.0,True
|
||||
2023-05-16 00:00:00+01:00,23.36,23.54,23.02,23.3,18.466981106041473,395998.0,0.0,0.0,True
|
||||
2023-05-17 00:00:00+01:00,23.56,23.580000000000002,22.68,22.84,18.102396185594404,423318.0,0.0,0.0,True
|
||||
2023-05-18 00:00:00+01:00,22.96,23.240000000000002,22.42,22.72,18.007289352520946,319457.0,0.0,0.0,True
|
||||
2023-05-19 00:00:00+01:00,22.5,22.9019091796875,22.04,22.46,17.80121775986271,421569.0,0.0,0.0,True
|
||||
2023-05-22 00:00:00+01:00,22.78,22.84,22.38,22.8,18.07069390790325,166747.0,0.0,0.0,True
|
||||
2023-05-23 00:00:00+01:00,23.2,23.22,22.38,22.38,17.737811265147336,309329.0,0.0,0.0,True
|
||||
2023-05-24 00:00:00+01:00,22.02,22.33969970703125,20.56,20.94,16.59650793560207,512827.0,0.0,0.0,True
|
||||
2023-05-25 00:00:00+01:00,20.52,21.0,20.32,20.32,16.10511002572425,729567.0,0.0,0.0,True
|
||||
2023-05-26 00:00:00+01:00,20.88,20.88,19.72,19.78,15.677119580228338,492367.0,0.0,0.0,True
|
||||
2023-05-30 00:00:00+01:00,19.92,20.0152001953125,19.35,19.41,15.383867208752699,690501.0,0.0,0.0,True
|
||||
2023-05-31 00:00:00+01:00,20.2,20.2,19.19,19.45,15.415570456110391,317942.0,0.0,0.0,True
|
||||
2023-06-01 00:00:00+01:00,19.66,19.740000000000002,19.150000000000002,19.47,15.431421942440583,304732.0,0.0,0.0,True
|
||||
2023-06-02 00:00:00+01:00,20.22,20.22,19.37,19.82,15.708823639936469,278304.0,0.0,0.0,True
|
||||
2023-06-05 00:00:00+01:00,19.62,19.72,17.92,18.17,15.690483393097194,461315.0,1.6,0.0,True
|
||||
2023-06-06 00:00:00+01:00,18.07,18.18,17.29,17.45,15.06873653968668,828912.0,0.0,0.0,True
|
||||
2023-06-07 00:00:00+01:00,17.73,18.41,17.73,18.32,15.820013943573676,554274.0,0.0,0.0,True
|
||||
2023-06-08 00:00:00+01:00,17.61,18.6747998046875,17.61,18.22,15.733660243256018,270247.0,0.0,0.0,True
|
||||
2023-06-09 00:00:00+01:00,18.330000000000002,18.63,17.93,18.52,15.992722399826066,341997.0,0.0,0.0,True
|
||||
2023-06-12 00:00:00+01:00,18.19,19.12,18.143199462890625,19.12,16.51084354611489,357760.0,0.0,0.0,True
|
||||
2023-06-13 00:00:00+01:00,19.2,19.77,18.94,19.400000000000002,16.75263475149799,648503.0,0.0,0.0,True
|
||||
2023-06-14 00:00:00+01:00,19.740000000000002,19.92,19.27,19.6,16.925343207750384,362355.0,0.0,0.0,True
|
||||
2023-06-15 00:00:00+01:00,19.6,19.775000000000002,18.96,19.18,16.56265639967574,437837.0,0.0,0.0,True
|
||||
2023-06-16 00:00:00+01:00,19.87,19.87,19.065,19.41,16.76126969928292,635867.0,0.0,0.0,True
|
||||
2023-06-19 00:00:00+01:00,19.37,19.37,18.93,18.95,16.364043100068553,343892.0,0.0,0.0,True
|
||||
2023-06-20 00:00:00+01:00,19.39,19.39,18.61,18.67,16.12225189468546,240994.0,0.0,0.0,True
|
||||
2023-06-21 00:00:00+01:00,19.45,19.469520263671875,18.36,18.91,16.329501197694658,276880.0,0.0,0.0,True
|
||||
2023-06-22 00:00:00+01:00,18.95,19.162230224609374,18.37,18.8,16.234512549592075,186330.0,0.0,0.0,True
|
||||
2023-06-23 00:00:00+01:00,18.6,19.04,18.6,18.87,16.294959295320766,189003.0,0.0,0.0,True
|
||||
2023-06-26 00:00:00+01:00,19.0,19.04719970703125,18.32,18.57,16.035899249984894,411820.0,0.0,0.0,True
|
||||
2023-06-27 00:00:00+01:00,18.650000000000002,18.77,17.669100341796874,18.03,15.569588846022732,538190.0,0.0,0.0,True
|
||||
2023-06-28 00:00:00+01:00,18.0,18.2,17.92,18.2,15.716389292069072,210732.0,0.0,0.0,True
|
||||
2023-06-29 00:00:00+01:00,18.7,18.7,17.54,17.59,15.189631086761139,253575.0,0.0,0.0,True
|
||||
2023-06-30 00:00:00+01:00,17.67,18.11,17.43,18.1,15.63003559175142,150826.0,0.0,0.0,True
|
||||
2023-07-03 00:00:00+01:00,17.900000000000002,18.36,17.88,18.330000000000002,15.8286488913586,791780.0,0.0,0.0,True
|
||||
2023-07-04 00:00:00+01:00,18.400000000000002,18.522430419921875,18.12,18.42,15.906367643891324,287173.0,0.0,0.0,True
|
||||
2023-07-05 00:00:00+01:00,18.56,18.580000000000002,18.255999755859374,18.36,15.85455479033048,160679.0,0.0,0.0,True
|
||||
2023-07-06 00:00:00+01:00,18.5,18.54,17.240000000000002,17.51,15.120548337630435,281127.0,0.0,0.0,True
|
||||
2023-07-07 00:00:00+01:00,17.51,17.51,16.69,17.1,14.766497532957805,290241.0,0.0,0.0,True
|
||||
2023-07-10 00:00:00+01:00,17.240000000000002,17.77,16.87,16.95,14.636966982481328,339775.0,0.0,0.0,True
|
||||
2023-07-11 00:00:00+01:00,17.5,17.5,16.12,16.14,13.93750137653809,371758.0,0.0,0.0,True
|
||||
2023-07-12 00:00:00+01:00,16.15,17.14,16.12,16.88,14.576519181135554,494734.0,0.0,0.0,True
|
||||
2023-07-13 00:00:00+01:00,17.0,17.330000000000002,16.85,16.89,14.585155184537573,155535.0,0.0,0.0,True
|
||||
2023-07-14 00:00:00+01:00,16.8,17.55,16.62,17.12,14.783768484144755,208870.0,0.0,0.0,True
|
||||
2023-07-17 00:00:00+01:00,17.0,17.17,16.740000000000002,16.9,14.593790132322503,155692.0,0.0,0.0,True
|
||||
2023-07-18 00:00:00+01:00,17.72,17.72,16.64,16.68,14.403811780500247,132785.0,0.0,0.0,True
|
||||
2023-07-19 00:00:00+01:00,17.1,17.62,16.87530029296875,17.62,15.215536985733017,396633.0,0.0,0.0,True
|
||||
2023-07-20 00:00:00+01:00,17.82,17.97,17.59,17.63,15.224172989135036,372626.0,0.0,0.0,True
|
||||
2023-07-21 00:00:00+01:00,17.86,18.063800048828124,17.6,17.88,15.44005723992917,257740.0,0.0,0.0,True
|
||||
2023-07-24 00:00:00+01:00,17.6,18.041500244140625,17.48,17.71,15.29325573826574,360104.0,0.0,0.0,True
|
||||
2023-07-25 00:00:00+01:00,17.740000000000002,18.22,17.57154052734375,17.86,15.422786288742218,209875.0,0.0,0.0,True
|
||||
2023-07-26 00:00:00+01:00,17.77,18.13,17.71,17.78,15.353704595228603,282136.0,0.0,0.0,True
|
||||
2023-07-27 00:00:00+01:00,17.78,18.19,17.7,18.06,15.595493689377525,198157.0,0.0,0.0,True
|
||||
2023-07-28 00:00:00+01:00,18.25,18.25,17.900000000000002,18.0,15.543681891433767,134365.0,0.0,0.0,True
|
||||
2023-07-31 00:00:00+01:00,17.990000000000002,18.0,17.448499755859377,17.62,15.215536985733017,266973.0,0.0,0.0,True
|
||||
2023-08-01 00:00:00+01:00,17.44,17.44,14.77,15.8,13.643898373211236,1707985.0,0.0,0.0,True
|
||||
2023-08-02 00:00:00+01:00,15.700000000000001,16.15,15.700000000000001,15.860000000000001,13.695711226772081,597276.0,0.0,0.0,True
|
||||
2023-08-03 00:00:00+01:00,15.700000000000001,15.875,15.56,15.66,13.523003826136776,720097.0,0.0,0.0,True
|
||||
2023-08-04 00:00:00+01:00,15.89,15.89,15.2875,15.450000000000001,13.341660422099453,130835.0,0.0,0.0,True
|
||||
2023-08-07 00:00:00+01:00,15.23,15.73,14.88,14.98,12.935797819483069,133228.0,0.0,0.0,True
|
||||
2023-08-08 00:00:00+01:00,14.8,15.18,14.65,14.93,12.892619913707154,187614.0,0.0,0.0,True
|
||||
2023-08-09 00:00:00+01:00,15.72,15.9,14.955999755859375,15.06,13.004880568613773,384876.0,0.0,0.0,True
|
||||
2023-08-10 00:00:00+01:00,15.06,15.11,14.450000000000001,14.5,12.521299213464665,509873.0,0.0,0.0,True
|
||||
2023-08-11 00:00:00+01:00,15.0,15.07,14.6,14.75,12.737183464258797,498841.0,0.0,0.0,True
|
||||
2023-08-14 00:00:00+01:00,14.75,15.32,14.75,15.11,13.0480574187726,202173.0,0.0,0.0,True
|
||||
2023-08-15 00:00:00+01:00,15.120000000000001,15.18,14.68,14.84,12.81490221679152,167723.0,0.0,0.0,True
|
||||
2023-08-16 00:00:00+01:00,14.89,15.08,14.51,14.790000000000001,12.771725366632696,172976.0,0.0,0.0,True
|
||||
2023-08-17 00:00:00+01:00,14.790000000000001,15.32,14.47,14.950000000000001,12.909890864894102,145057.0,0.0,0.0,True
|
||||
2023-08-18 00:00:00+01:00,14.4,14.96,14.4,14.85,12.823538220193539,246954.0,0.0,0.0,True
|
||||
2023-08-21 00:00:00+01:00,15.16,15.16,14.73,14.85,12.823538220193539,208997.0,0.0,0.0,True
|
||||
2023-08-22 00:00:00+01:00,14.82,15.17,14.75,14.85,12.823538220193539,89056.0,0.0,0.0,True
|
||||
2023-08-23 00:00:00+01:00,14.56,15.05,14.56,14.71,12.702641561884901,494801.0,0.0,0.0,True
|
||||
2023-08-24 00:00:00+01:00,14.98,14.993909912109375,14.71,14.71,12.702641561884901,102654.0,0.0,0.0,True
|
||||
2023-08-25 00:00:00+01:00,15.44,15.44,14.700000000000001,14.77,12.754454415445746,136975.0,0.0,0.0,True
|
||||
2023-08-29 00:00:00+01:00,14.96,15.52,14.85,15.49,13.376201268856262,146752.0,0.0,0.0,True
|
||||
2023-08-30 00:00:00+01:00,15.49,15.624000244140625,15.18,15.38,13.28121262075368,259486.0,0.0,0.0,True
|
||||
2023-08-31 00:00:00+01:00,15.35,15.51,15.18,15.25,13.168953021464148,312027.0,0.0,0.0,True
|
||||
2023-09-01 00:00:00+01:00,15.38,15.41,14.950000000000001,14.99,12.944432767268001,122627.0,0.0,0.0,True
|
||||
2023-09-04 00:00:00+01:00,14.99,15.1,14.83,14.83,12.80626726900659,138450.0,0.0,0.0,True
|
||||
2023-09-05 00:00:00+01:00,14.8,14.83199951171875,14.42,14.66,12.659464711726075,173206.0,0.0,0.0,True
|
||||
2023-09-06 00:00:00+01:00,15.0,15.040000000000001,14.44,14.81,12.788996317819642,194887.0,0.0,0.0,True
|
||||
2023-09-07 00:00:00+01:00,14.83,15.6,14.46,15.530000000000001,13.410743171230159,243553.0,0.0,0.0,True
|
||||
2023-09-08 00:00:00+01:00,15.0,15.89,15.0,15.89,13.721617125743958,339473.0,0.0,0.0,True
|
||||
2023-09-11 00:00:00+01:00,16.22,16.32,14.68,14.73,12.719912513071849,274162.0,0.0,0.0,True
|
||||
2023-09-12 00:00:00+01:00,14.4,14.55,12.620000000000001,14.05,12.13270756203523,695308.0,0.0,0.0,True
|
||||
2023-09-13 00:00:00+01:00,14.09,15.47,13.790000000000001,15.44,13.333024418697434,359608.0,0.0,0.0,True
|
||||
2023-09-14 00:00:00+01:00,15.5,16.126199951171877,15.5,16.07,13.877053575192315,818615.0,0.0,0.0,True
|
||||
2023-09-15 00:00:00+01:00,16.31,16.32,15.57,15.63,13.497097927164898,470826.0,0.0,0.0,True
|
||||
2023-09-18 00:00:00+01:00,15.44,15.85,15.169410400390625,15.22,13.143046066875181,388020.0,0.0,0.0,True
|
||||
2023-09-19 00:00:00+01:00,15.11,15.58,14.9039599609375,15.32,13.229400822809922,244500.0,0.0,0.0,True
|
||||
2023-09-20 00:00:00+01:00,15.44,16.02,15.44,15.88,13.712982177959029,260949.0,0.0,0.0,True
|
||||
2023-09-21 00:00:00+01:00,15.610000000000001,15.83,15.0,15.19,13.117140167903305,380456.0,0.0,0.0,True
|
||||
2023-09-22 00:00:00+01:00,15.1,15.48,15.1,15.35,13.255306721781801,144967.0,0.0,0.0,True
|
||||
2023-09-25 00:00:00+01:00,15.35,15.6,14.960999755859376,15.19,13.117140167903305,326513.0,0.0,0.0,True
|
||||
2023-09-26 00:00:00+01:00,15.58,15.58,14.58,14.63,12.633558812754195,139051.0,0.0,0.0,True
|
||||
2023-09-27 00:00:00+01:00,14.58,15.34,14.48,15.13,13.065328369959548,140879.0,0.0,0.0,True
|
||||
2023-09-28 00:00:00+01:00,15.120000000000001,15.19,14.83,15.0,12.953067715052928,345116.0,0.0,0.0,True
|
||||
2023-09-29 00:00:00+01:00,15.0,15.610000000000001,15.0,15.47,13.358930317669312,256397.0,0.0,0.0,True
|
||||
2023-10-02 00:00:00+01:00,15.46,15.67,14.870000000000001,15.040000000000001,12.987609617426825,291241.0,0.0,0.0,True
|
||||
2023-10-03 00:00:00+01:00,14.71,14.89,14.0,14.05,12.13270756203523,179006.0,0.0,0.0,True
|
||||
2023-10-04 00:00:00+01:00,13.83,14.290000000000001,13.77,13.81,11.925458259026028,237634.0,0.0,0.0,True
|
||||
2023-10-05 00:00:00+01:00,13.92,14.17,13.85,13.85,11.9599997746206,180284.0,0.0,0.0,True
|
||||
2023-10-06 00:00:00+01:00,14.450000000000001,14.450000000000001,13.55,13.99,12.080894818697017,116485.0,0.0,0.0,True
|
||||
2023-10-09 00:00:00+01:00,13.52,14.030000000000001,13.41,13.620000000000001,11.761386337214,136545.0,0.0,0.0,True
|
||||
2023-10-10 00:00:00+01:00,13.89,14.55,13.72,14.55,12.564476049970086,245926.0,0.0,0.0,True
|
||||
2023-10-11 00:00:00+01:00,14.32,14.52,13.450000000000001,13.52,12.438399456418825,134243.0,0.85,0.0,True
|
||||
2023-10-12 00:00:00+01:00,14.0,14.0,13.38,13.51,12.429199958107466,112363.0,0.0,0.0,True
|
||||
2023-10-13 00:00:00+01:00,13.46,13.75,13.1,13.1,12.052000296313045,264982.0,0.0,0.0,True
|
||||
2023-10-16 00:00:00+01:00,13.1,13.42699951171875,12.69,13.31,12.245199876365936,142869.0,0.0,0.0,True
|
||||
2023-10-17 00:00:00+01:00,13.21,13.479949951171875,13.09300048828125,13.370000000000001,12.300400238072205,103846.0,0.0,0.0,True
|
||||
2023-10-18 00:00:00+01:00,13.5,13.5,12.69,12.75,11.729999872278858,586500.0,0.0,0.0,True
|
||||
2023-10-19 00:00:00+01:00,12.52,13.213499755859376,12.52,13.11,12.061199794624404,200672.0,0.0,0.0,True
|
||||
2023-10-20 00:00:00+01:00,13.07,13.41,12.83,13.18,12.125599654642036,592696.0,0.0,0.0,True
|
||||
2023-10-23 00:00:00+01:00,13.25,13.4,13.0,13.33,12.263599996934692,121413.0,0.0,0.0,True
|
||||
2023-10-24 00:00:00+01:00,13.42,13.64,13.0,13.1,12.052000296313045,173527.0,0.0,0.0,True
|
||||
2023-10-25 00:00:00+01:00,13.09,13.34,12.96,13.14,12.088799413504523,113657.0,0.0,0.0,True
|
||||
2023-10-26 00:00:00+01:00,13.0,13.280000000000001,12.96,13.1,12.052000296313045,162088.0,0.0,0.0,True
|
||||
2023-10-27 00:00:00+01:00,13.1,13.16,12.85,13.0,11.959999693469262,172121.0,0.0,0.0,True
|
||||
2023-10-30 00:00:00+00:00,13.09,13.200000000000001,12.99,13.06,12.015200055175532,351486.0,0.0,0.0,True
|
||||
2023-10-31 00:00:00+00:00,13.01,13.3,13.0,13.05,12.005999432918136,380834.0,0.0,0.0,True
|
||||
2023-11-01 00:00:00+00:00,12.950000000000001,13.120000000000001,12.77843994140625,13.02,11.978399814038019,199402.0,0.0,0.0,True
|
||||
2023-11-02 00:00:00+00:00,13.1,13.46,13.040000000000001,13.34,12.272799495246051,414055.0,0.0,0.0,True
|
||||
2023-11-03 00:00:00+00:00,13.6,14.415000000000001,13.52384033203125,14.0,12.880000102176911,348357.0,0.0,0.0,True
|
||||
2023-11-06 00:00:00+00:00,14.13,14.48,13.530000000000001,13.66,12.56720030040012,95127.0,0.0,0.0,True
|
||||
2023-11-07 00:00:00+00:00,13.5,13.93,13.5,13.84,12.732800261572894,164937.0,0.0,0.0,True
|
||||
2023-11-08 00:00:00+00:00,13.74,14.0456005859375,13.69,13.8,12.696000020435381,275526.0,0.0,0.0,True
|
||||
2023-11-09 00:00:00+00:00,13.950000000000001,14.19,13.71550048828125,13.85,12.741999759884255,308199.0,0.0,0.0,True
|
||||
2023-11-10 00:00:00+00:00,13.73,13.834399414062501,13.22,13.620000000000001,12.530400059262607,211940.0,0.0,0.0,True
|
||||
2023-11-13 00:00:00+00:00,13.5,13.72,13.4,13.55,12.466000199244979,206951.0,0.0,0.0,True
|
||||
2023-11-14 00:00:00+00:00,13.5,14.41,13.42,14.14,13.008799822212172,714971.0,0.0,0.0,True
|
||||
2023-11-15 00:00:00+00:00,14.290000000000001,14.99,14.030000000000001,14.52,13.358399865126476,430958.0,0.0,0.0,True
|
||||
2023-11-16 00:00:00+00:00,14.08,14.505,14.08,14.23,13.091599802798559,193252.0,0.0,0.0,True
|
||||
2023-11-17 00:00:00+00:00,14.11,14.99,14.11,14.82,13.63439942576575,474070.0,0.0,0.0,True
|
||||
2023-11-20 00:00:00+00:00,14.77,15.120000000000001,14.77,14.98,13.781600390315806,127160.0,0.0,0.0,True
|
||||
2023-11-21 00:00:00+00:00,14.98,15.31,14.85,14.88,13.689599787472021,312023.0,0.0,0.0,True
|
||||
2023-11-22 00:00:00+00:00,14.84,15.19,14.8,14.94,13.744800149178293,93813.0,0.0,0.0,True
|
||||
2023-11-23 00:00:00+00:00,14.96,15.055,14.67,14.88,13.689599787472021,89248.0,0.0,0.0,True
|
||||
2023-11-24 00:00:00+00:00,14.76,14.9,14.67,14.85,13.662000168591906,118893.0,0.0,0.0,True
|
||||
2023-11-27 00:00:00+00:00,14.530000000000001,14.86,13.98,13.98,12.861599981608155,129900.0,0.0,0.0,True
|
||||
2023-11-28 00:00:00+00:00,13.84,14.14,13.19,13.34,12.272799495246051,377366.0,0.0,0.0,True
|
||||
2023-11-29 00:00:00+00:00,13.200000000000001,14.35,13.200000000000001,13.950000000000001,12.834000362728037,471577.0,0.0,0.0,True
|
||||
2023-11-30 00:00:00+00:00,13.8,14.11800048828125,13.44,13.68,12.585600420968879,348127.0,0.0,0.0,True
|
||||
2023-12-01 00:00:00+00:00,13.700000000000001,13.84,13.576400146484374,13.73,12.631600160417753,352771.0,0.0,0.0,True
|
||||
2023-12-04 00:00:00+00:00,14.0,14.0,13.120000000000001,13.16,12.107199534073278,104065.0,0.0,0.0,True
|
||||
2023-12-05 00:00:00+00:00,13.07,13.200000000000001,12.6,13.0,11.959999693469262,303748.0,0.0,0.0,True
|
||||
2023-12-06 00:00:00+00:00,12.9,13.26,12.9,13.02,11.978399814038019,681974.0,0.0,0.0,True
|
||||
2023-12-07 00:00:00+00:00,13.4,13.4,12.56,12.82,11.794399732296489,193151.0,0.0,0.0,True
|
||||
2023-12-08 00:00:00+00:00,12.85,12.98,12.64,12.76,11.73919937059022,169002.0,0.0,0.0,True
|
||||
2023-12-11 00:00:00+00:00,12.700000000000001,13.530000000000001,12.700000000000001,13.36,12.291199615814808,316496.0,0.0,0.0,True
|
||||
2023-12-12 00:00:00+00:00,13.33,13.36,12.948399658203126,13.26,12.199200136917062,279752.0,0.0,0.0,True
|
||||
2023-12-13 00:00:00+00:00,13.4,13.48,13.16,13.41,12.337199355263682,223452.0,0.0,0.0,True
|
||||
2023-12-14 00:00:00+00:00,13.8,14.59,13.74,14.3,13.155999662816189,258358.0,0.0,0.0,True
|
||||
2023-12-15 00:00:00+00:00,13.71,14.31,13.71,14.13,12.999600323900811,433550.0,0.0,0.0,True
|
||||
2023-12-18 00:00:00+00:00,14.38,15.33740966796875,13.89,15.290000000000001,14.06679944926644,256957.0,0.0,0.0,True
|
||||
2023-12-19 00:00:00+00:00,15.290000000000001,15.700000000000001,15.040000000000001,15.46,14.223199912127853,152997.0,0.0,0.0,True
|
||||
2023-12-20 00:00:00+00:00,15.75,15.92,15.33,15.83,14.563599332784761,258981.0,0.0,0.0,True
|
||||
2023-12-21 00:00:00+00:00,15.73,16.03,15.34,16.02,14.73839991621493,160788.0,0.0,0.0,True
|
||||
2023-12-22 00:00:00+00:00,16.0,16.543089599609374,15.73,16.35,15.042000219680359,183509.0,0.0,0.0,True
|
||||
2023-12-27 00:00:00+00:00,16.1,16.95,16.0,16.69,15.354800021457152,332319.0,0.0,0.0,True
|
||||
2023-12-28 00:00:00+00:00,16.29,16.95,16.0,16.6,15.272000040870765,129658.0,0.0,0.0,True
|
||||
2023-12-29 00:00:00+00:00,16.66,16.77678955078125,16.606290283203126,16.62,15.29040016143952,54474.0,0.0,0.0,True
|
||||
2024-01-02 00:00:00+00:00,16.9,16.93,15.950000000000001,15.98,14.701599675077418,433331.0,0.0,0.0,True
|
||||
2024-01-03 00:00:00+00:00,16.45,16.45,15.583499755859375,15.8,14.535999713904644,212305.0,0.0,0.0,True
|
||||
2024-01-04 00:00:00+00:00,16.18,16.2,15.32,15.5,14.260000153265366,145849.0,0.0,0.0,True
|
||||
2024-01-05 00:00:00+00:00,15.43,15.63,14.84,15.34,14.112800312661351,178331.0,0.0,0.0,True
|
||||
2024-01-08 00:00:00+00:00,15.200000000000001,15.88,15.08,15.3,14.076000071523838,93619.0,0.0,0.0,True
|
||||
2024-01-09 00:00:00+00:00,15.450000000000001,15.32,15.21,15.280000000000001,14.05759995095508,236053.0,0.0,0.0,True
|
||||
2024-01-10 00:00:00+00:00,15.21,15.51,15.120000000000001,15.16,13.947200351488577,203338.0,0.0,0.0,True
|
||||
2024-01-11 00:00:00+00:00,15.21,15.44,14.73,14.73,13.551599445179363,128350.0,0.0,0.0,True
|
||||
2024-01-12 00:00:00+00:00,14.81,15.3,14.81,15.280000000000001,14.05759995095508,126422.0,0.0,0.0,True
|
||||
2024-01-15 00:00:00+00:00,15.085,15.32,14.86,14.86,13.671199666903265,86831.0,0.0,0.0,True
|
||||
2024-01-16 00:00:00+00:00,15.08,15.66,14.91,15.39,14.158800052110225,253055.0,0.0,0.0,True
|
||||
2024-01-17 00:00:00+00:00,15.040000000000001,15.5,14.450000000000001,14.540000000000001,13.37679998569523,114336.0,0.0,0.0,True
|
||||
2024-01-18 00:00:00+00:00,14.9,15.22,14.59,15.22,14.002399589248812,175262.0,0.0,0.0,True
|
||||
2024-01-19 00:00:00+00:00,15.450000000000001,15.450000000000001,14.89,14.89,13.698800409729419,93241.0,0.0,0.0,True
|
||||
2024-01-22 00:00:00+00:00,15.11,15.15,14.835,15.05,13.846000250333434,92117.0,0.0,0.0,True
|
||||
2024-01-23 00:00:00+00:00,14.51,15.63,14.51,15.3,14.076000071523838,96389.0,0.0,0.0,True
|
||||
2024-01-24 00:00:00+00:00,15.530000000000001,15.74,15.200000000000001,15.74,14.480799352198373,278489.0,0.0,0.0,True
|
||||
2024-01-25 00:00:00+00:00,15.32,15.84550048828125,15.030000000000001,15.55,14.30599989271424,476735.0,0.0,0.0,True
|
||||
2024-01-26 00:00:00+00:00,15.66,16.11,15.26,15.99,14.710800297334815,417225.0,0.0,0.0,True
|
||||
2024-01-29 00:00:00+00:00,15.91,16.240000000000002,15.69,16.240000000000002,14.940800118525216,112434.0,0.0,0.0,True
|
||||
2024-01-30 00:00:00+00:00,16.1,16.740000000000002,16.080000000000002,16.65,15.317999780319637,156730.0,0.0,0.0,True
|
||||
2024-01-31 00:00:00+00:00,15.99,16.84,15.99,16.6,15.272000040870765,249055.0,0.0,0.0,True
|
||||
2024-02-01 00:00:00+00:00,16.55,16.89,16.44,16.78,15.437600002043538,230759.0,0.0,0.0,True
|
||||
2024-02-02 00:00:00+00:00,16.69,17.0,16.46,16.46,15.143200320835506,170565.0,0.0,0.0,True
|
||||
2024-02-05 00:00:00+00:00,16.26,16.79,16.175,16.31,15.005199978542848,130266.0,0.0,0.0,True
|
||||
2024-02-06 00:00:00+00:00,16.4,17.07,16.38,16.78,15.437600002043538,391036.0,0.0,0.0,True
|
||||
2024-02-07 00:00:00+00:00,16.7,17.16,16.55,17.09,15.72280018494021,215847.0,0.0,0.0,True
|
||||
2024-02-08 00:00:00+00:00,17.150000000000002,17.91,17.150000000000002,17.44,16.04479948502836,450151.0,0.0,0.0,True
|
||||
2024-02-09 00:00:00+00:00,17.46,17.80198974609375,17.07,17.18,15.805600165526597,242803.0,0.0,0.0,True
|
||||
2024-02-12 00:00:00+00:00,17.25,17.84,16.96,16.990000000000002,15.630799582096428,563881.0,0.0,0.0,True
|
||||
2024-02-13 00:00:00+00:00,16.85,16.885140380859376,16.330000000000002,16.51,15.189200060284378,68119.0,0.0,0.0,True
|
||||
2024-02-14 00:00:00+00:00,16.37,17.17,16.18530029296875,17.03,15.667599823233939,98220.0,0.0,0.0,True
|
||||
2024-02-15 00:00:00+00:00,16.51,17.39,16.51,16.96,15.603199963216312,102797.0,0.0,0.0,True
|
||||
2024-02-16 00:00:00+00:00,16.990000000000002,17.330000000000002,16.990000000000002,17.07,15.704400064371454,47249.0,0.0,0.0,True
|
||||
2024-02-19 00:00:00+00:00,17.07,17.271500244140626,16.82,17.14,15.768799924389086,465791.0,0.0,0.0,True
|
||||
2024-02-20 00:00:00+00:00,17.0,17.0,16.12,16.12,14.830399395112678,117840.0,0.0,0.0,True
|
||||
2024-02-21 00:00:00+00:00,16.44,16.52,16.09,16.18,14.885599756818946,616655.0,0.0,0.0,True
|
||||
2024-02-22 00:00:00+00:00,15.99,16.69,15.5,16.59,15.262799418613366,71029.0,0.0,0.0,True
|
||||
2024-02-23 00:00:00+00:00,16.61,16.66,15.9,16.2,14.903999877387704,616927.0,0.0,0.0,True
|
||||
2024-02-26 00:00:00+00:00,15.9,16.24449951171875,15.56,15.700000000000001,14.444000235006898,125089.0,0.0,0.0,True
|
||||
2024-02-27 00:00:00+00:00,15.5,15.88,15.34,15.57,14.324400013282999,506414.0,0.0,0.0,True
|
||||
2024-02-28 00:00:00+00:00,15.0,15.6,13.540000000000001,14.46,13.303199503420204,1617451.0,0.0,0.0,True
|
||||
2024-02-29 00:00:00+00:00,14.700000000000001,14.99,14.27,14.34,13.192799903953702,131744.0,0.0,0.0,True
|
||||
2024-03-01 00:00:00+00:00,14.52,14.83,14.0,14.68,13.505599705730491,710016.0,0.0,0.0,True
|
||||
2024-03-04 00:00:00+00:00,14.3,14.790000000000001,14.3,14.450000000000001,13.294000005108844,128631.0,0.0,0.0,True
|
||||
2024-03-05 00:00:00+00:00,14.43,14.5,14.13,14.3,13.155999662816189,226847.0,0.0,0.0,True
|
||||
2024-03-06 00:00:00+00:00,14.35,14.6,14.13,14.13,12.999600323900811,245345.0,0.0,0.0,True
|
||||
2024-03-07 00:00:00+00:00,14.36,14.36,13.55,13.55,12.466000199244979,169908.0,0.0,0.0,True
|
||||
2024-03-08 00:00:00+00:00,13.55,13.84,13.26,13.3,12.236000378054575,591778.0,0.0,0.0,True
|
||||
2024-03-11 00:00:00+00:00,13.450000000000001,13.6,13.15,13.25,12.189999514659664,537344.0,0.0,0.0,True
|
||||
2024-03-12 00:00:00+00:00,13.0,13.74,13.0,13.700000000000001,12.603999417591599,652597.0,0.0,0.0,True
|
||||
2024-03-13 00:00:00+00:00,14.5,15.65,13.521639404296875,13.72,12.622399538160355,1195682.0,0.0,0.0,True
|
||||
2024-03-14 00:00:00+00:00,13.82,14.59,13.34,14.32,13.174399783384944,1126694.0,0.0,0.0,True
|
||||
2024-03-15 00:00:00+00:00,14.3,14.56,14.02,14.26,13.119199421678676,1525658.0,0.0,0.0,True
|
||||
2024-03-18 00:00:00+00:00,14.34,14.620000000000001,14.02,14.24,13.100800425055956,462513.0,0.0,0.0,True
|
||||
2024-03-19 00:00:00+00:00,14.24,14.48,13.81,13.81,12.705199518746742,496898.0,0.0,0.0,True
|
||||
2024-03-20 00:00:00+00:00,13.83,14.02,12.780000000000001,13.33,12.263599996934692,340715.0,0.0,0.0,True
|
||||
2024-03-21 00:00:00+00:00,13.48,13.809000244140625,13.23,13.34,12.272799495246051,276189.0,0.0,0.0,True
|
||||
2024-03-22 00:00:00+00:00,13.44,13.58,13.120000000000001,13.13,12.079599915193162,477630.0,0.0,0.0,True
|
||||
2024-03-25 00:00:00+00:00,13.5,13.5,12.64,12.64,11.628799771123717,437124.0,0.0,0.0,True
|
||||
2024-03-26 00:00:00+00:00,12.64,13.0,12.410699462890625,12.56,11.555200412794726,1102700.0,0.0,0.0,True
|
||||
2024-03-27 00:00:00+00:00,12.5,12.77,12.38,12.58,11.573599409417445,1158042.0,0.0,0.0,True
|
||||
2024-03-28 00:00:00+00:00,12.68,13.32,12.455,13.02,11.978399814038019,672275.0,0.0,0.0,True
|
||||
2024-04-02 00:00:00+01:00,12.9,13.13,12.38,12.46,11.463199809950943,420287.0,0.0,0.0,True
|
||||
2024-04-03 00:00:00+01:00,12.280000000000001,12.49,11.99,12.22,11.2423994870719,460217.0,0.0,0.0,True
|
||||
2024-04-04 00:00:00+01:00,12.200000000000001,12.17,12.0,12.0,11.040000408707648,293870.0,0.0,0.0,True
|
||||
2024-04-05 00:00:00+01:00,11.98,12.037879638671875,11.6,11.65,10.717999984673462,395059.0,0.0,0.0,True
|
||||
2024-04-08 00:00:00+01:00,11.61,12.120000000000001,11.495000000000001,12.06,11.095199646467881,810772.0,0.0,0.0,True
|
||||
2024-04-09 00:00:00+01:00,12.0,12.15,11.790000000000001,11.91,10.957200428121261,413918.0,0.0,0.0,True
|
||||
2024-04-10 00:00:00+01:00,11.950000000000001,12.33,11.8725,12.01,11.049199907019009,680979.0,0.0,0.0,True
|
||||
2024-04-11 00:00:00+01:00,12.08,12.31,11.868509521484375,11.94,10.984800047001379,280220.0,0.0,0.0,True
|
||||
2024-04-12 00:00:00+01:00,12.06,12.290000000000001,11.4,11.450000000000001,10.533999902931932,359653.0,0.0,0.0,True
|
||||
2024-04-15 00:00:00+01:00,11.41,11.57,11.01,11.4,10.488000163483058,489256.0,0.0,0.0,True
|
||||
2024-04-16 00:00:00+01:00,11.200000000000001,11.78,11.07,11.51,10.589200264638203,294117.0,0.0,0.0,True
|
||||
2024-04-17 00:00:00+01:00,11.5,11.81050048828125,11.4,11.620000000000001,10.690400365793346,446216.0,0.0,0.0,True
|
||||
2024-04-18 00:00:00+01:00,11.43,11.83,11.43,11.71,10.773200346379733,280345.0,0.0,0.0,True
|
||||
2024-04-19 00:00:00+01:00,11.8,11.8,11.56,11.68,10.745599603553579,187448.0,0.0,0.0,True
|
||||
2024-04-22 00:00:00+01:00,11.5,12.06,11.5,11.72,10.782399844691094,233273.0,0.0,0.0,True
|
||||
2024-04-23 00:00:00+01:00,11.870000000000001,11.89,11.72,11.72,10.782399844691094,164436.0,0.0,0.0,True
|
||||
2024-04-24 00:00:00+01:00,12.08,12.08,11.370000000000001,11.51,10.589200264638203,185184.0,0.0,0.0,True
|
||||
2024-04-25 00:00:00+01:00,11.700000000000001,11.700000000000001,11.1,11.36,10.451199922345545,295818.0,0.0,0.0,True
|
||||
2024-04-26 00:00:00+01:00,11.31,11.64,11.230880126953124,11.39,10.478799541225662,144819.0,0.0,0.0,True
|
||||
2024-04-29 00:00:00+01:00,11.15,11.82,11.15,11.82,10.874400447534875,119071.0,0.0,0.0,True
|
||||
2024-04-30 00:00:00+01:00,11.98,11.99,11.42,11.5,10.579999642380805,199939.0,0.0,0.0,True
|
||||
2024-05-01 00:00:00+01:00,12.01,12.01,11.32,11.59,10.662799622967192,165171.0,0.0,0.0,True
|
||||
2024-05-02 00:00:00+01:00,11.57,11.66,11.3,11.66,10.727199482984823,305855.0,0.0,0.0,True
|
||||
2024-05-03 00:00:00+01:00,11.85,11.96,11.6,11.75,10.80999946357121,158727.0,0.0,0.0,True
|
||||
2024-05-07 00:00:00+01:00,12.13,12.19,11.57,11.790000000000001,10.846799704708722,116963.0,0.0,0.0,True
|
||||
2024-05-08 00:00:00+01:00,12.15,12.804000244140624,11.99,12.67,11.656399390003832,362985.0,0.0,0.0,True
|
||||
2024-05-09 00:00:00+01:00,12.65,12.71,12.18,12.66,11.647199891692471,261229.0,0.0,0.0,True
|
||||
2024-05-10 00:00:00+01:00,12.47,12.97,12.47,12.89,11.858799592314119,187666.0,0.0,0.0,True
|
||||
2024-05-13 00:00:00+01:00,12.8,13.120000000000001,12.58,12.8,11.775999611727732,164449.0,0.0,0.0,True
|
||||
2024-05-14 00:00:00+01:00,12.6,13.237950439453126,12.6,13.08,12.033600175744288,166908.0,0.0,0.0,True
|
||||
2024-05-15 00:00:00+01:00,13.36,13.48,13.030000000000001,13.450000000000001,12.373999596401195,178857.0,0.0,0.0,True
|
||||
2024-05-16 00:00:00+01:00,13.450000000000001,14.0,13.450000000000001,14.0,12.880000102176911,314200.0,0.0,0.0,True
|
||||
2024-05-17 00:00:00+01:00,14.13,14.8,13.780000000000001,14.700000000000001,13.523999826299248,558689.0,0.0,0.0,True
|
||||
2024-05-20 00:00:00+01:00,24.5,24.98,22.82,22.82,20.994399323588837,8292215.0,0.0,0.0,True
|
||||
2024-05-21 00:00:00+01:00,23.02,23.44,22.400000000000002,22.56,20.755198880141037,1407097.0,0.0,0.0,True
|
||||
2024-05-22 00:00:00+01:00,22.46,22.64,22.0,22.0,20.24,723017.0,0.0,0.0,True
|
||||
2024-05-23 00:00:00+01:00,21.98,22.47597900390625,21.62,22.3,22.3,1522184.0,1.76,0.0,False
|
||||
2024-05-24 00:00:00+01:00,22.240000000000002,22.3,21.68,22.14,22.14,644971.0,0.0,0.0,False
|
||||
2024-05-28 00:00:00+01:00,22.2,22.6,22.06,22.5,22.5,311246.0,0.0,0.0,False
|
||||
2024-05-29 00:00:00+01:00,22.48,22.6010009765625,22.16,22.3,22.3,1482854.0,0.0,0.0,False
|
||||
2024-05-30 00:00:00+01:00,22.5,22.62,22.3,22.32,22.32,138373.0,0.0,0.0,False
|
||||
2024-05-31 00:00:00+01:00,22.0,22.48,22.0,22.34,22.34,695505.0,0.0,0.0,False
|
||||
2024-06-03 00:00:00+01:00,22.2,22.48,22.1,22.36,22.36,148218.0,0.0,0.0,False
|
||||
2024-06-04 00:00:00+01:00,22.36,22.36,21.75,22.0,22.0,1289764.0,0.0,0.0,False
|
||||
2024-06-05 00:00:00+01:00,22.36,22.36,21.8,22.02,22.02,295325.0,0.0,0.0,False
|
||||
2024-06-06 00:00:00+01:00,22.02,22.145700683593752,21.78,22.04,22.04,463598.0,0.0,0.0,False
|
||||
2024-06-07 00:00:00+01:00,22.1,22.2,21.740000000000002,21.98,21.98,799873.0,0.0,0.0,False
|
||||
2024-06-10 00:00:00+01:00,21.900000000000002,22.02,21.64,21.64,21.64,588812.0,0.0,0.0,False
|
||||
2024-06-11 00:00:00+01:00,21.84,22.1,21.400000000000002,21.42,21.42,323278.0,0.0,0.0,False
|
||||
2024-06-12 00:00:00+01:00,21.72,21.72,21.2,21.5,21.5,961776.0,0.0,0.0,False
|
||||
2024-06-13 00:00:00+01:00,21.7,21.7,21.0,21.36,21.36,731949.0,0.0,0.0,False
|
||||
2024-06-14 00:00:00+01:00,21.72,22.62,21.435,22.62,22.62,1564845.0,0.0,0.0,False
|
||||
2024-06-17 00:00:00+01:00,22.42,22.60555908203125,22.05300048828125,22.3,22.3,543001.0,0.0,0.0,False
|
||||
2024-06-18 00:00:00+01:00,22.5,22.5,22.011999511718752,22.28,22.28,302283.0,0.0,0.0,False
|
||||
2024-06-19 00:00:00+01:00,22.0,22.36,21.94,22.0,22.0,261639.0,0.0,0.0,False
|
||||
2024-06-20 00:00:00+01:00,22.5,22.5,21.900000000000002,22.400000000000002,22.400000000000002,298140.0,0.0,0.0,False
|
||||
2024-06-21 00:00:00+01:00,22.5,22.900000000000002,22.22,22.38,22.38,374718.0,0.0,0.0,False
|
||||
2024-06-24 00:00:00+01:00,22.400000000000002,22.62,22.2,22.38,22.38,182607.0,0.0,0.0,False
|
||||
2024-06-25 00:00:00+01:00,22.3,22.32,21.32049072265625,21.92,21.92,1156786.0,0.0,0.0,False
|
||||
2024-06-26 00:00:00+01:00,22.0,22.0,21.44,21.740000000000002,21.740000000000002,1321707.0,0.0,0.0,False
|
||||
2024-06-27 00:00:00+01:00,21.86,21.92,21.6,21.78,21.78,1192605.0,0.0,0.0,False
|
||||
2024-06-28 00:00:00+01:00,23.1,23.21093994140625,22.88800048828125,23.12,23.12,5166863.0,0.0,0.0,False
|
||||
2024-07-01 00:00:00+01:00,23.26,23.26,23.06,23.080000000000002,23.080000000000002,904708.0,0.0,0.0,False
|
||||
2024-07-02 00:00:00+01:00,23.080000000000002,23.240000000000002,23.06,23.18,23.18,800296.0,0.0,0.0,False
|
||||
2024-07-03 00:00:00+01:00,23.84,23.900000000000002,23.78333984375,23.900000000000002,23.900000000000002,8961383.0,0.0,0.0,False
|
||||
2024-07-04 00:00:00+01:00,23.92,23.94,23.83340087890625,23.86,23.86,1175939.0,0.0,0.0,False
|
||||
2024-07-05 00:00:00+01:00,23.900000000000002,23.96,23.86,23.88,23.88,969052.0,0.0,0.0,False
|
||||
2024-07-08 00:00:00+01:00,23.88,24.060000000000002,23.88,23.88,23.88,420214.0,0.0,0.0,False
|
||||
2024-07-09 00:00:00+01:00,23.92,23.96,23.86,23.900000000000002,23.900000000000002,1264139.0,0.0,0.0,False
|
||||
2024-07-10 00:00:00+01:00,23.88,23.94,23.88,23.900000000000002,23.900000000000002,371085.0,0.0,0.0,False
|
||||
2024-07-11 00:00:00+01:00,23.84,23.92,23.82,23.82,23.82,458586.0,0.0,0.0,False
|
||||
2024-07-12 00:00:00+01:00,23.82,23.88,23.82,23.88,23.88,681277.0,0.0,0.0,False
|
||||
2024-07-15 00:00:00+01:00,23.84,23.88,23.84,23.86,23.86,739304.0,0.0,0.0,False
|
||||
2024-07-16 00:00:00+01:00,23.88,23.883859863281252,23.84,23.86,23.86,1130090.0,0.0,0.0,False
|
||||
2024-07-17 00:00:00+01:00,23.88,23.88,23.86,23.86,23.86,755831.0,0.0,0.0,False
|
||||
2024-07-18 00:00:00+01:00,23.88,23.900000000000002,23.86,23.900000000000002,23.900000000000002,960170.0,0.0,0.0,False
|
||||
2024-07-19 00:00:00+01:00,23.900000000000002,23.94,23.86,23.94,23.94,195271.0,0.0,0.0,False
|
||||
2024-07-22 00:00:00+01:00,23.88,23.92,23.8,23.84,23.84,3036352.0,0.0,0.0,False
|
||||
2024-07-23 00:00:00+01:00,23.82,23.86,23.8,23.82,23.82,1083480.0,0.0,0.0,False
|
||||
2024-07-24 00:00:00+01:00,23.84,23.88,23.8,23.8,23.8,1445489.0,0.0,0.0,False
|
||||
2024-07-25 00:00:00+01:00,23.84,23.900000000000002,23.8,23.8,23.8,582850.0,0.0,0.0,False
|
||||
2024-07-26 00:00:00+01:00,23.96,23.96,23.8,23.8,23.8,675264.0,0.0,0.0,False
|
||||
2024-07-29 00:00:00+01:00,23.84,23.88,23.5783203125,23.84,23.84,1403210.0,0.0,0.0,False
|
||||
2024-07-30 00:00:00+01:00,23.84,23.88,23.82,23.84,23.84,1286201.0,0.0,0.0,False
|
||||
2024-07-31 00:00:00+01:00,23.86,23.88,23.82,23.88,23.88,308556.0,0.0,0.0,False
|
||||
2024-08-01 00:00:00+01:00,23.900000000000002,23.900000000000002,23.84,23.84,23.84,139383.0,0.0,0.0,False
|
||||
2024-08-02 00:00:00+01:00,24.2,24.2,23.84,23.84,23.84,402227.0,0.0,0.0,False
|
||||
2024-08-05 00:00:00+01:00,23.84,23.88,23.8,23.88,23.88,2543161.0,0.0,0.0,False
|
||||
2024-08-06 00:00:00+01:00,23.900000000000002,24.060000000000002,23.82,23.88,23.88,805371.0,0.0,0.0,False
|
||||
2024-08-07 00:00:00+01:00,23.900000000000002,23.92,23.84,23.86,23.86,1753790.0,0.0,0.0,False
|
||||
2024-08-08 00:00:00+01:00,23.86,23.92,23.86,23.88,23.88,191998.0,0.0,0.0,False
|
||||
2024-08-09 00:00:00+01:00,23.900000000000002,23.98,23.86,23.98,23.98,289215.0,0.0,0.0,False
|
||||
2024-08-12 00:00:00+01:00,23.96,24.0,23.92,24.0,24.0,513766.0,0.0,0.0,False
|
||||
2024-08-13 00:00:00+01:00,24.0,24.04,23.94,24.04,24.04,185320.0,0.0,0.0,False
|
||||
2024-08-14 00:00:00+01:00,24.0,24.3,23.96,24.3,24.3,300442.0,0.0,0.0,False
|
||||
2024-08-15 00:00:00+01:00,24.1,24.12,24.0,24.02,24.02,222740.0,0.0,0.0,False
|
||||
2024-08-16 00:00:00+01:00,24.1,24.1,23.98,23.98,23.98,255770.0,0.0,0.0,False
|
||||
2024-08-19 00:00:00+01:00,24.080000000000002,24.080000000000002,23.96,24.0,24.0,229725.0,0.0,0.0,False
|
||||
2024-08-20 00:00:00+01:00,24.0,24.04,23.98,24.0,24.0,261084.0,0.0,0.0,False
|
||||
2024-08-21 00:00:00+01:00,24.080000000000002,24.080000000000002,23.98,24.060000000000002,24.060000000000002,1086506.0,0.0,0.0,False
|
||||
2024-08-22 00:00:00+01:00,24.080000000000002,24.080000000000002,24.02,24.060000000000002,24.060000000000002,163317.0,0.0,0.0,False
|
||||
2024-08-23 00:00:00+01:00,24.080000000000002,24.080000000000002,24.0,24.080000000000002,24.080000000000002,202364.0,0.0,0.0,False
|
||||
2024-08-27 00:00:00+01:00,24.060000000000002,24.18,24.02,24.060000000000002,24.060000000000002,245203.0,0.0,0.0,False
|
||||
2024-08-28 00:00:00+01:00,24.02,24.12,24.02,24.04,24.04,349423.0,0.0,0.0,False
|
||||
2024-08-29 00:00:00+01:00,24.04,24.12,24.04,24.060000000000002,24.060000000000002,187436.0,0.0,0.0,False
|
||||
2024-08-30 00:00:00+01:00,24.16,24.3,24.02,24.26,24.26,1493472.0,0.0,0.0,False
|
||||
2024-09-02 00:00:00+01:00,24.240000000000002,24.28,24.22,24.240000000000002,24.240000000000002,397048.0,0.0,0.0,False
|
||||
2024-09-03 00:00:00+01:00,24.240000000000002,24.28,24.22,24.22,24.22,526456.0,0.0,0.0,False
|
||||
2024-09-04 00:00:00+01:00,24.240000000000002,24.33919921875,24.22,24.240000000000002,24.240000000000002,830622.0,0.0,0.0,False
|
||||
2024-09-05 00:00:00+01:00,24.26,24.28,24.240000000000002,24.240000000000002,24.240000000000002,2561655.0,0.0,0.0,False
|
||||
2024-09-06 00:00:00+01:00,24.240000000000002,24.3,24.240000000000002,24.240000000000002,24.240000000000002,2621382.0,0.0,0.0,False
|
||||
2024-09-09 00:00:00+01:00,24.240000000000002,24.333601074218752,24.240000000000002,24.26,24.26,946993.0,0.0,0.0,False
|
||||
2024-09-10 00:00:00+01:00,24.28,24.38,24.240000000000002,24.28,24.28,1955248.0,0.0,0.0,False
|
||||
2024-09-11 00:00:00+01:00,24.28,24.3,24.255720214843752,24.26,24.26,3357431.0,0.0,0.0,False
|
||||
2024-09-12 00:00:00+01:00,24.28,24.32,24.26,24.3,24.3,1396090.0,0.0,0.0,False
|
||||
2024-09-13 00:00:00+01:00,24.26,24.3,24.26,24.26,24.26,539753.0,0.0,0.0,False
|
||||
2024-09-16 00:00:00+01:00,24.28,24.3,24.26,24.28,24.28,3548116.0,0.0,0.0,False
|
||||
2024-09-17 00:00:00+01:00,24.3,24.3143994140625,24.28,24.28,24.28,6116775.0,0.0,0.0,False
|
||||
2024-09-18 00:00:00+01:00,24.28,24.3,24.26,24.28,24.28,1315109.0,0.0,0.0,False
|
||||
2024-09-19 00:00:00+01:00,24.28,24.307199707031252,24.28,24.28,24.28,3447049.0,0.0,0.0,False
|
||||
2024-09-20 00:00:00+01:00,24.28,24.301000976562502,24.28,24.3,24.3,949712.0,0.0,0.0,False
|
||||
2024-09-23 00:00:00+01:00,24.3,24.34,24.28,24.28,24.28,1165867.0,0.0,0.0,False
|
||||
2024-09-24 00:00:00+01:00,24.3,24.34,24.29,24.3,24.3,417334.0,0.0,0.0,False
|
||||
2024-09-25 00:00:00+01:00,24.32,24.356000976562502,24.28,24.32,24.32,1311755.0,0.0,0.0,False
|
||||
2024-09-26 00:00:00+01:00,24.3,24.36,24.3,24.32,24.32,2165924.0,0.0,0.0,False
|
||||
2024-09-27 00:00:00+01:00,24.34,24.385,24.32,24.34,24.34,191057.0,0.0,0.0,False
|
||||
2024-09-30 00:00:00+01:00,24.36,24.36,24.3,24.36,24.36,418219.0,0.0,0.0,False
|
||||
2024-10-01 00:00:00+01:00,24.36,24.38,24.34,24.34,24.34,834978.0,0.0,0.0,False
|
||||
2024-10-02 00:00:00+01:00,24.34,24.38,24.34,24.36,24.36,321113.0,0.0,0.0,False
|
||||
2024-10-03 00:00:00+01:00,24.36,24.400000000000002,24.36,24.36,24.36,119311.0,0.0,0.0,False
|
||||
2024-10-04 00:00:00+01:00,24.400000000000002,24.400000000000002,24.355380859375,24.38,24.38,408506.0,0.0,0.0,False
|
||||
2024-10-07 00:00:00+01:00,24.400000000000002,24.400000000000002,24.36,24.400000000000002,24.400000000000002,934866.0,0.0,0.0,False
|
||||
2024-10-08 00:00:00+01:00,24.38,24.400000000000002,24.36,24.38,24.38,351909.0,0.0,0.0,False
|
||||
2024-10-09 00:00:00+01:00,24.400000000000002,24.400000000000002,24.36,24.36,24.36,373356.0,0.0,0.0,False
|
||||
2024-10-10 00:00:00+01:00,24.36,24.400000000000002,24.36,24.38,24.38,566301.0,0.0,0.0,False
|
||||
2024-10-11 00:00:00+01:00,24.400000000000002,24.400000000000002,24.36,24.38,24.38,88197.0,0.0,0.0,False
|
||||
2024-10-14 00:00:00+01:00,24.42,24.42,24.36,24.36,24.36,2859472.0,0.0,0.0,False
|
||||
2024-10-15 00:00:00+01:00,24.38,24.42,24.38,24.400000000000002,24.400000000000002,1387949.0,0.0,0.0,False
|
||||
2024-10-16 00:00:00+01:00,24.42,24.42,24.38,24.38,24.38,518018.0,0.0,0.0,False
|
||||
2024-10-17 00:00:00+01:00,24.42,24.42,24.378291015625,24.38,24.38,1199504.0,0.0,0.0,False
|
||||
2024-10-18 00:00:00+01:00,24.400000000000002,24.52,24.38,24.400000000000002,24.400000000000002,612904.0,0.0,0.0,False
|
||||
2024-10-21 00:00:00+01:00,24.42,24.46,24.42,24.44,24.44,937999.0,0.0,0.0,False
|
||||
2024-10-22 00:00:00+01:00,24.46,24.48,24.44,24.46,24.46,9890907.0,0.0,0.0,False
|
||||
2024-10-23 00:00:00+01:00,24.46,24.46,24.46,24.46,24.46,0.0,0.0,0.0,False
|
||||
2024-10-24 00:00:00+01:00,,,,,,,0.0,0.0,False
|
||||
2024-10-25 00:00:00+01:00,,,,,,,0.0,0.0,False
|
||||
2024-10-28 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-10-29 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-10-30 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-10-31 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-01 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-04 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-05 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-06 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-07 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-08 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-11 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-12 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-13 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
2024-11-14 00:00:00+00:00,,,,,,,0.0,0.0,False
|
||||
|
@@ -1,725 +0,0 @@
|
||||
Datetime,Open,High,Low,Close,Adj Close,Volume,Dividends,Stock Splits
|
||||
2022-01-04 00:00:00+00:00,29.46,29.98,28.52,28.66,28.56770263671875,169521.0,0.0,0.0
|
||||
2022-01-05 00:00:00+00:00,30.0,30.0,28.46,28.900000000000002,28.806928710937502,128698.0,0.0,0.0
|
||||
2022-01-06 00:00:00+00:00,28.2,28.560000000000002,27.5,27.82,27.73040771484375,374659.0,0.0,0.0
|
||||
2022-01-07 00:00:00+00:00,28.3,28.3,27.400000000000002,27.46,27.37156982421875,80410.0,0.0,0.0
|
||||
2022-01-10 00:00:00+00:00,28.16,28.240000000000002,26.2,26.580000000000002,26.494404296875,135881.0,0.0,0.0
|
||||
2022-01-11 00:00:00+00:00,25.92,27.060000000000002,25.92,26.72,26.6339501953125,71414.0,0.0,0.0
|
||||
2022-01-12 00:00:00+00:00,26.72,26.96,26.060000000000002,26.8,26.713693847656252,68611.0,0.0,0.0
|
||||
2022-01-13 00:00:00+00:00,26.72,27.3239990234375,26.6,27.2,27.11240478515625,155917.0,0.0,0.0
|
||||
2022-01-14 00:00:00+00:00,27.52,27.52,26.36,26.560000000000002,26.474470214843752,66402.0,0.0,0.0
|
||||
2022-01-17 00:00:00+00:00,27.02,27.22,26.28,27.22,27.13234619140625,60092.0,0.0,0.0
|
||||
2022-01-18 00:00:00+00:00,27.66,27.66,26.0,26.86,26.773500976562502,128385.0,0.0,0.0
|
||||
2022-01-19 00:00:00+00:00,27.0,27.46,26.7,27.2,27.11240478515625,75141.0,0.0,0.0
|
||||
2022-01-20 00:00:00+00:00,26.900000000000002,27.7,26.81172119140625,27.54,27.45131103515625,99304.0,0.0,0.0
|
||||
2022-01-21 00:00:00+00:00,27.26,27.88,26.214208984375002,26.38,26.295048828125,123570.0,0.0,0.0
|
||||
2022-01-24 00:00:00+00:00,26.14,26.261599121093752,24.72,24.88,24.799875488281252,148794.0,0.0,0.0
|
||||
2022-01-25 00:00:00+00:00,24.92,25.2,24.580000000000002,24.580000000000002,24.5008447265625,94318.0,0.0,0.0
|
||||
2022-01-26 00:00:00+00:00,25.52,25.52,24.400000000000002,24.66,24.58058349609375,265198.0,0.0,0.0
|
||||
2022-01-27 00:00:00+00:00,24.66,25.12669921875,24.400000000000002,24.82,24.74007080078125,248811.0,0.0,0.0
|
||||
2022-01-28 00:00:00+00:00,24.7,24.88,24.1,24.32,24.2416845703125,146209.0,0.0,0.0
|
||||
2022-01-31 00:00:00+00:00,25.3,25.46,24.3,25.2,25.11884765625,495745.0,0.0,0.0
|
||||
2022-02-01 00:00:00+00:00,25.580000000000002,26.78,25.580000000000002,26.7,26.614016113281252,426366.0,0.0,0.0
|
||||
2022-02-02 00:00:00+00:00,25.5,27.28,25.5,26.38,26.295048828125,134118.0,0.0,0.0
|
||||
2022-02-03 00:00:00+00:00,26.28,26.3639990234375,24.82,24.88,24.799875488281252,168782.0,0.0,0.0
|
||||
2022-02-04 00:00:00+00:00,24.6,25.14,24.400000000000002,24.76,24.680263671875,110543.0,0.0,0.0
|
||||
2022-02-07 00:00:00+00:00,25.04,25.04,24.54,24.54,24.460974121093752,163853.0,0.0,0.0
|
||||
2022-02-08 00:00:00+00:00,24.64,24.64,23.8,24.12,24.04232421875,146007.0,0.0,0.0
|
||||
2022-02-09 00:00:00+00:00,24.5,24.98,24.3,24.7,24.62045654296875,130747.0,0.0,0.0
|
||||
2022-02-10 00:00:00+00:00,24.52,24.7,24.080000000000002,24.46,24.38123046875,113862.0,0.0,0.0
|
||||
2022-02-11 00:00:00+00:00,24.5,24.72,24.1,24.42,24.34135986328125,87108.0,0.0,0.0
|
||||
2022-02-14 00:00:00+00:00,24.42,24.42,23.34,23.98,23.90277587890625,79188.0,0.0,0.0
|
||||
2022-02-15 00:00:00+00:00,23.86,24.560000000000002,23.54,24.22,24.142001953125,175846.0,0.0,0.0
|
||||
2022-02-16 00:00:00+00:00,24.580000000000002,24.580000000000002,23.76,23.98,23.90277587890625,62392.0,0.0,0.0
|
||||
2022-02-17 00:00:00+00:00,24.78,24.78,23.86,23.86,23.7831640625,111791.0,0.0,0.0
|
||||
2022-02-18 00:00:00+00:00,23.84,23.94760009765625,23.36,23.48,23.404384765625,61467.0,0.0,0.0
|
||||
2022-02-21 00:00:00+00:00,23.46,23.64919921875,22.82,23.080000000000002,23.00567138671875,71820.0,0.0,0.0
|
||||
2022-02-22 00:00:00+00:00,24.18,24.18,22.54,23.38,23.30470703125,75721.0,0.0,0.0
|
||||
2022-02-23 00:00:00+00:00,23.78,24.04,23.02,23.02,22.945869140625,122317.0,0.0,0.0
|
||||
2022-02-24 00:00:00+00:00,23.3,23.3,21.96,22.52,22.44747802734375,241118.0,0.0,0.0
|
||||
2022-02-25 00:00:00+00:00,23.0,23.56,22.66,23.32,23.24490234375,147148.0,0.0,0.0
|
||||
2022-02-28 00:00:00+00:00,22.36,24.14,22.36,24.14,24.062258300781252,226698.0,0.0,0.0
|
||||
2022-03-01 00:00:00+00:00,24.080000000000002,24.22,23.5,23.5,23.42432373046875,218356.0,0.0,0.0
|
||||
2022-03-02 00:00:00+00:00,23.7,23.900000000000002,23.26,23.62,23.54393798828125,87219.0,0.0,0.0
|
||||
2022-03-03 00:00:00+00:00,23.26,23.8,22.14,22.14,22.068701171875002,137377.0,0.0,0.0
|
||||
2022-03-04 00:00:00+00:00,22.3,22.92,20.740000000000002,20.740000000000002,20.67321044921875,173972.0,0.0,0.0
|
||||
2022-03-07 00:00:00+00:00,20.740000000000002,21.14,19.5,20.3,20.234625244140627,282380.0,0.0,0.0
|
||||
2022-03-08 00:00:00+00:00,20.3,20.82,19.52,19.52,19.457138671875,268763.0,0.0,0.0
|
||||
2022-03-09 00:00:00+00:00,20.0,21.02,19.73,21.02,20.9523095703125,624876.0,0.0,0.0
|
||||
2022-03-10 00:00:00+00:00,21.22,21.22,20.38,20.44,20.374176025390625,266261.0,0.0,0.0
|
||||
2022-03-11 00:00:00+00:00,20.66,21.52,20.46,20.900000000000002,20.8326953125,139879.0,0.0,0.0
|
||||
2022-03-14 00:00:00+00:00,21.5,21.88,21.1,21.580000000000002,21.51050537109375,87051.0,0.0,0.0
|
||||
2022-03-15 00:00:00+00:00,20.72,21.48,20.72,20.96,20.89250244140625,86783.0,0.0,0.0
|
||||
2022-03-16 00:00:00+00:00,21.580000000000002,22.72,21.36,22.48,22.40760986328125,118783.0,0.0,0.0
|
||||
2022-03-17 00:00:00+00:00,21.68,22.7,21.68,22.46,22.387670898437502,86717.0,0.0,0.0
|
||||
2022-03-18 00:00:00+00:00,21.76,23.32,21.76,23.18,23.10535400390625,147084.0,0.0,0.0
|
||||
2022-03-21 00:00:00+00:00,23.400000000000002,23.400000000000002,22.26,22.62,22.547155761718752,290436.0,0.0,0.0
|
||||
2022-03-22 00:00:00+00:00,23.22,23.22,21.94,22.0,21.929150390625,89172.0,0.0,0.0
|
||||
2022-03-23 00:00:00+00:00,21.68,22.7,21.68,22.56,22.487348632812502,83842.0,0.0,0.0
|
||||
2022-03-24 00:00:00+00:00,21.42,22.64,21.400000000000002,22.400000000000002,22.3278662109375,121267.0,0.0,0.0
|
||||
2022-03-25 00:00:00+00:00,22.5,23.1,21.92,22.66,22.5870263671875,192618.0,0.0,0.0
|
||||
2022-03-28 00:00:00+01:00,22.14,23.32,22.14,22.86,22.78638427734375,109333.0,0.0,0.0
|
||||
2022-03-29 00:00:00+01:00,23.02,23.511201171875,22.8360009765625,23.38,23.30470703125,85895.0,0.0,0.0
|
||||
2022-03-30 00:00:00+01:00,23.82,25.740000000000002,23.82,25.740000000000002,25.657109375,571137.0,0.0,0.0
|
||||
2022-03-31 00:00:00+01:00,25.68,26.2,25.0,26.2,26.11562255859375,458165.0,0.0,0.0
|
||||
2022-04-01 00:00:00+01:00,26.32,26.34,25.580000000000002,25.580000000000002,25.497622070312502,206616.0,0.0,0.0
|
||||
2022-04-04 00:00:00+01:00,26.400000000000002,26.400000000000002,25.2,25.92,25.836530761718752,150039.0,0.0,0.0
|
||||
2022-04-05 00:00:00+01:00,25.94,26.92,25.900000000000002,26.46,26.3747900390625,2241719.0,0.0,0.0
|
||||
2022-04-06 00:00:00+01:00,26.62,26.98,26.32,26.52,26.43459716796875,178598.0,0.0,0.0
|
||||
2022-04-07 00:00:00+01:00,26.86,27.62,26.44,27.18,27.092470703125002,191304.0,0.0,0.0
|
||||
2022-04-08 00:00:00+01:00,27.52,27.72489990234375,26.52,26.62,26.534277343750002,131026.0,0.0,0.0
|
||||
2022-04-11 00:00:00+01:00,26.560000000000002,26.692480468750002,25.88,26.0,25.91627197265625,106445.0,0.0,0.0
|
||||
2022-04-12 00:00:00+01:00,26.0,26.580000000000002,26.0,26.28,26.19536865234375,134222.0,0.0,0.0
|
||||
2022-04-13 00:00:00+01:00,26.62,26.62,25.92,26.3,26.21530517578125,151567.0,0.0,0.0
|
||||
2022-04-14 00:00:00+01:00,26.240000000000002,26.52,25.79534912109375,26.0,25.91627197265625,203268.0,0.0,0.0
|
||||
2022-04-19 00:00:00+01:00,25.8,26.060000000000002,24.96,25.54,25.45775146484375,202763.0,0.0,0.0
|
||||
2022-04-20 00:00:00+01:00,25.740000000000002,25.740000000000002,25.12,25.12,25.039106445312502,133972.0,0.0,0.0
|
||||
2022-04-21 00:00:00+01:00,25.22,25.62,25.1,25.2,25.11884765625,134423.0,0.0,0.0
|
||||
2022-04-22 00:00:00+01:00,24.62,25.38,24.62,25.02,24.93942626953125,148749.0,0.0,0.0
|
||||
2022-04-25 00:00:00+01:00,24.38,24.86,24.18,24.400000000000002,24.32142333984375,283575.0,0.0,0.0
|
||||
2022-04-26 00:00:00+01:00,24.3,24.82,24.22,24.3,24.221743164062502,271554.0,0.0,0.0
|
||||
2022-04-27 00:00:00+01:00,24.0,24.94,23.2,23.46,23.38445068359375,147954.0,0.0,0.0
|
||||
2022-04-28 00:00:00+01:00,23.48,23.90139892578125,23.42,23.76,23.68348388671875,98816.0,0.0,0.0
|
||||
2022-04-29 00:00:00+01:00,23.22,24.16,23.2,24.04,23.9625830078125,139578.0,0.0,0.0
|
||||
2022-05-03 00:00:00+01:00,23.6,24.3,23.18,23.48,23.404384765625,181511.0,0.0,0.0
|
||||
2022-05-04 00:00:00+01:00,23.16,23.26,22.24698974609375,22.44,22.36773681640625,199215.0,0.0,0.0
|
||||
2022-05-05 00:00:00+01:00,23.52,23.52,22.18,22.26,22.1883154296875,468283.0,0.0,0.0
|
||||
2022-05-06 00:00:00+01:00,21.900000000000002,22.06,21.5,22.0,21.929150390625,119246.0,0.0,0.0
|
||||
2022-05-09 00:00:00+01:00,21.88,21.89320068359375,20.8,21.14,21.07192138671875,216918.0,0.0,0.0
|
||||
2022-05-10 00:00:00+01:00,21.3,22.02,21.14,21.52,21.4506982421875,175912.0,0.0,0.0
|
||||
2022-05-11 00:00:00+01:00,22.080000000000002,22.6,21.48,21.92,21.849409179687502,161619.0,0.0,0.0
|
||||
2022-05-12 00:00:00+01:00,21.54,22.0,21.0,21.96,21.88927978515625,162789.0,0.0,0.0
|
||||
2022-05-13 00:00:00+01:00,22.0,22.580000000000002,21.88,22.400000000000002,22.3278662109375,136027.0,0.0,0.0
|
||||
2022-05-16 00:00:00+01:00,22.28,22.32,21.66,21.88,21.80953857421875,169593.0,0.0,0.0
|
||||
2022-05-17 00:00:00+01:00,21.94,22.1,21.580000000000002,21.8,21.7297998046875,230442.0,0.0,0.0
|
||||
2022-05-18 00:00:00+01:00,22.76,22.76,21.34,21.36,21.29121337890625,218130.0,0.0,0.0
|
||||
2022-05-19 00:00:00+01:00,21.56,21.900000000000002,20.82,21.82,21.74973388671875,161985.0,0.0,0.0
|
||||
2022-05-20 00:00:00+01:00,21.88,22.5,21.7,21.76,21.689924316406252,108143.0,0.0,0.0
|
||||
2022-05-23 00:00:00+01:00,21.7,22.26,21.68,21.84,21.76966552734375,114671.0,0.0,0.0
|
||||
2022-05-24 00:00:00+01:00,22.0,22.0,21.22,21.34,21.271279296875,80311.0,0.0,0.0
|
||||
2022-05-25 00:00:00+01:00,21.44,22.240000000000002,21.3510009765625,21.94,21.869345703125,108379.0,0.0,0.0
|
||||
2022-05-26 00:00:00+01:00,22.240000000000002,22.240000000000002,21.66,22.080000000000002,22.023447265625002,54302.0,1.45,0.0
|
||||
2022-05-27 00:00:00+01:00,22.14,22.68,22.04,22.5,22.44237548828125,84161.0,0.0,0.0
|
||||
2022-05-30 00:00:00+01:00,22.8,23.1,22.5,22.68,22.6219140625,92952.0,0.0,0.0
|
||||
2022-05-31 00:00:00+01:00,22.0,23.56,22.0,23.42,23.36001708984375,260541.0,0.0,0.0
|
||||
2022-06-01 00:00:00+01:00,23.52,23.76,22.96,23.48,23.41986328125,169299.0,0.0,0.0
|
||||
2022-06-06 00:00:00+01:00,23.52,23.76,23.080000000000002,23.56,23.49966064453125,62642.0,0.0,0.0
|
||||
2022-06-07 00:00:00+01:00,22.62,23.92,22.62,23.8,23.73904541015625,131089.0,0.0,0.0
|
||||
2022-06-08 00:00:00+01:00,23.88,24.22,23.88,24.060000000000002,23.99837646484375,144324.0,0.0,0.0
|
||||
2022-06-09 00:00:00+01:00,23.72,24.740000000000002,23.48300048828125,24.32,24.25771240234375,197024.0,0.0,0.0
|
||||
2022-06-10 00:00:00+01:00,24.18,24.5,23.68,23.900000000000002,23.838789062500002,391211.0,0.0,0.0
|
||||
2022-06-13 00:00:00+01:00,23.78,24.0,22.88,23.2,23.1405810546875,389306.0,0.0,0.0
|
||||
2022-06-14 00:00:00+01:00,23.18,23.34,22.92,23.04,22.9809912109375,168973.0,0.0,0.0
|
||||
2022-06-15 00:00:00+01:00,22.6,23.18,21.580000000000002,22.26,22.20299072265625,159033.0,0.0,0.0
|
||||
2022-06-16 00:00:00+01:00,22.54,22.54,21.82,21.92,21.86385986328125,154582.0,0.0,0.0
|
||||
2022-06-17 00:00:00+01:00,22.02,22.62,22.0,22.56,22.5022216796875,162701.0,0.0,0.0
|
||||
2022-06-20 00:00:00+01:00,22.54,22.7643994140625,22.3,22.46,22.402475585937502,48492.0,0.0,0.0
|
||||
2022-06-21 00:00:00+01:00,22.52,23.1,22.34,22.740000000000002,22.68176025390625,131960.0,0.0,0.0
|
||||
2022-06-22 00:00:00+01:00,22.94,23.12,22.03,22.96,22.9011962890625,67403.0,0.0,0.0
|
||||
2022-06-23 00:00:00+01:00,23.5,23.5,21.88,22.240000000000002,22.183037109375,191595.0,0.0,0.0
|
||||
2022-06-24 00:00:00+01:00,22.8,23.34,22.580000000000002,23.1,23.04083984375,186503.0,0.0,0.0
|
||||
2022-06-27 00:00:00+01:00,23.080000000000002,23.34,22.78,22.900000000000002,22.84134765625,75108.0,0.0,0.0
|
||||
2022-06-28 00:00:00+01:00,22.84,23.14,22.42,22.6,22.54211669921875,95713.0,0.0,0.0
|
||||
2022-06-29 00:00:00+01:00,22.44,22.580000000000002,21.76,21.8,21.74416748046875,143179.0,0.0,0.0
|
||||
2022-06-30 00:00:00+01:00,21.38,22.0,21.38,21.94,21.88380859375,143371.0,0.0,0.0
|
||||
2022-07-01 00:00:00+01:00,21.0,22.3,21.0,22.14,22.083295898437502,151912.0,0.0,0.0
|
||||
2022-07-04 00:00:00+01:00,22.96,23.12,21.76,21.86,21.80401611328125,163031.0,0.0,0.0
|
||||
2022-07-05 00:00:00+01:00,21.8,22.26,21.1,21.54,21.4848291015625,87873.0,0.0,0.0
|
||||
2022-07-06 00:00:00+01:00,21.8,22.54,21.8,22.5,22.44237548828125,192002.0,0.0,0.0
|
||||
2022-07-07 00:00:00+01:00,22.740000000000002,22.86,22.44739990234375,22.68,22.6219140625,44045.0,0.0,0.0
|
||||
2022-07-08 00:00:00+01:00,22.7,23.1,22.38,23.0,22.94109130859375,54169.0,0.0,0.0
|
||||
2022-07-11 00:00:00+01:00,23.0,23.240000000000002,22.68,23.02,22.961042480468752,28404.0,0.0,0.0
|
||||
2022-07-12 00:00:00+01:00,23.48,23.48,22.38,22.400000000000002,22.3426318359375,58069.0,0.0,0.0
|
||||
2022-07-13 00:00:00+01:00,21.98,22.42,21.54,22.2,22.14314208984375,171315.0,0.0,0.0
|
||||
2022-07-14 00:00:00+01:00,21.6,22.28739990234375,21.42,21.8,21.74416748046875,69105.0,0.0,0.0
|
||||
2022-07-15 00:00:00+01:00,22.240000000000002,22.46,21.42,22.38,22.3226806640625,37962.0,0.0,0.0
|
||||
2022-07-18 00:00:00+01:00,22.52,23.26,22.52,23.1,23.04083984375,57375.0,0.0,0.0
|
||||
2022-07-19 00:00:00+01:00,22.86,23.240000000000002,22.86,23.080000000000002,23.02088623046875,111888.0,0.0,0.0
|
||||
2022-07-20 00:00:00+01:00,23.32,23.7,23.27,23.64,23.57945556640625,101102.0,0.0,0.0
|
||||
2022-07-21 00:00:00+01:00,23.6,24.3,23.52,24.3,24.237763671875,94675.0,0.0,0.0
|
||||
2022-07-22 00:00:00+01:00,24.22,24.66,24.14,24.28,24.21781494140625,106841.0,0.0,0.0
|
||||
2022-07-25 00:00:00+01:00,24.26,24.42,23.96,24.04,23.978430175781252,156132.0,0.0,0.0
|
||||
2022-07-26 00:00:00+01:00,24.1,24.1,23.56,23.56,23.49966064453125,100895.0,0.0,0.0
|
||||
2022-07-27 00:00:00+01:00,23.48,23.94,23.44,23.580000000000002,23.519609375,147619.0,0.0,0.0
|
||||
2022-07-28 00:00:00+01:00,24.32,24.400000000000002,23.84,24.400000000000002,24.337509765625,68667.0,0.0,0.0
|
||||
2022-07-29 00:00:00+01:00,24.28,25.48,24.26,25.14,25.07561279296875,215529.0,0.0,0.0
|
||||
2022-08-01 00:00:00+01:00,26.0,26.0,24.6,24.900000000000002,24.836225585937502,67096.0,0.0,0.0
|
||||
2022-08-02 00:00:00+01:00,24.86,24.900000000000002,24.3,24.52,24.4572021484375,44575.0,0.0,0.0
|
||||
2022-08-03 00:00:00+01:00,25.400000000000002,27.664499511718752,24.740000000000002,27.0,26.93085205078125,363560.0,0.0,0.0
|
||||
2022-08-04 00:00:00+01:00,26.96,27.06300048828125,25.98,26.42,26.352333984375,390933.0,0.0,0.0
|
||||
2022-08-05 00:00:00+01:00,26.28,27.1,26.22,26.54,26.4720263671875,281941.0,0.0,0.0
|
||||
2022-08-08 00:00:00+01:00,26.26,26.84,25.740000000000002,26.02,25.953359375,119579.0,0.0,0.0
|
||||
2022-08-09 00:00:00+01:00,26.0,26.12,25.400000000000002,25.42,25.354895019531252,81157.0,0.0,0.0
|
||||
2022-08-10 00:00:00+01:00,26.0,26.361459960937502,24.84,26.240000000000002,26.1727978515625,236333.0,0.0,0.0
|
||||
2022-08-11 00:00:00+01:00,26.22,26.52,25.94,26.26,26.192744140625,202521.0,0.0,0.0
|
||||
2022-08-12 00:00:00+01:00,26.740000000000002,26.76,26.12,26.68,26.61166748046875,94373.0,0.0,0.0
|
||||
2022-08-15 00:00:00+01:00,26.0,26.92,25.66,26.68,26.61166748046875,130154.0,0.0,0.0
|
||||
2022-08-16 00:00:00+01:00,26.1,26.86,25.34,25.580000000000002,25.5144873046875,220905.0,0.0,0.0
|
||||
2022-08-17 00:00:00+01:00,25.66,26.2,25.32,25.740000000000002,25.674074707031252,194549.0,0.0,0.0
|
||||
2022-08-18 00:00:00+01:00,25.740000000000002,25.8,25.42,25.8,25.7339208984375,73907.0,0.0,0.0
|
||||
2022-08-19 00:00:00+01:00,25.64,25.7,24.38,24.38,24.31755859375,161331.0,0.0,0.0
|
||||
2022-08-22 00:00:00+01:00,24.2,24.42,23.84,24.14,24.07817138671875,309805.0,0.0,0.0
|
||||
2022-08-23 00:00:00+01:00,24.2,24.2,23.34,23.42,23.36001708984375,169026.0,0.0,0.0
|
||||
2022-08-24 00:00:00+01:00,24.44,24.44,23.240000000000002,24.080000000000002,24.01832763671875,213735.0,0.0,0.0
|
||||
2022-08-25 00:00:00+01:00,24.34,24.76,24.14,24.560000000000002,24.49709716796875,103565.0,0.0,0.0
|
||||
2022-08-26 00:00:00+01:00,24.68,25.84,24.418798828125002,24.48,24.4173046875,111767.0,0.0,0.0
|
||||
2022-08-30 00:00:00+01:00,25.0,25.32,24.28,24.64,24.57689208984375,114667.0,0.0,0.0
|
||||
2022-08-31 00:00:00+01:00,24.3,25.14,24.26,24.86,24.79633056640625,159278.0,0.0,0.0
|
||||
2022-09-01 00:00:00+01:00,24.84,24.84,23.28,23.5,23.439814453125,75741.0,0.0,0.0
|
||||
2022-09-02 00:00:00+01:00,23.8,23.900000000000002,23.32,23.86,23.79889404296875,161878.0,0.0,0.0
|
||||
2022-09-05 00:00:00+01:00,23.54,24.04,23.19093994140625,23.5,23.439814453125,89772.0,0.0,0.0
|
||||
2022-09-06 00:00:00+01:00,23.54,24.02,23.31,23.580000000000002,23.519609375,71477.0,0.0,0.0
|
||||
2022-09-07 00:00:00+01:00,23.0,23.72,23.0,23.48,23.41986328125,97993.0,0.0,0.0
|
||||
2022-09-08 00:00:00+01:00,23.400000000000002,23.86,23.12,23.86,23.79889404296875,192900.0,0.0,0.0
|
||||
2022-09-09 00:00:00+01:00,23.7,24.240000000000002,23.67845947265625,24.16,24.098125,59221.0,0.0,0.0
|
||||
2022-09-12 00:00:00+01:00,24.400000000000002,24.400000000000002,23.82,24.04,23.978430175781252,76307.0,0.0,0.0
|
||||
2022-09-13 00:00:00+01:00,24.0,24.76,23.66,23.66,23.599401855468752,155869.0,0.0,0.0
|
||||
2022-09-14 00:00:00+01:00,23.66,24.34,23.54,23.84,23.778940429687502,120233.0,0.0,0.0
|
||||
2022-09-15 00:00:00+01:00,23.22,23.88,23.18,23.34,23.280222167968752,297665.0,0.0,0.0
|
||||
2022-09-16 00:00:00+01:00,23.26,23.32,22.900000000000002,22.92,22.861298828125,144960.0,0.0,0.0
|
||||
2022-09-20 00:00:00+01:00,22.94,24.04,22.6,23.5,23.439814453125,317042.0,0.0,0.0
|
||||
2022-09-21 00:00:00+01:00,23.84,24.36,21.86,23.12,23.0607861328125,273104.0,0.0,0.0
|
||||
2022-09-22 00:00:00+01:00,23.02,23.46,22.8,23.240000000000002,23.18048095703125,330760.0,0.0,0.0
|
||||
2022-09-23 00:00:00+01:00,23.02,23.14,21.900000000000002,22.56,22.5022216796875,152226.0,0.0,0.0
|
||||
2022-09-26 00:00:00+01:00,22.1,22.98,22.1,22.68,22.6219140625,160292.0,0.0,0.0
|
||||
2022-09-27 00:00:00+01:00,22.92,23.52,22.82,22.82,22.761552734375,170562.0,0.0,0.0
|
||||
2022-09-28 00:00:00+01:00,22.1,23.06,21.98,22.86,22.80145263671875,115333.0,0.0,0.0
|
||||
2022-09-29 00:00:00+01:00,22.84,22.900000000000002,22.04,22.36,22.30273193359375,131444.0,0.0,0.0
|
||||
2022-09-30 00:00:00+01:00,22.7,23.18,22.0,22.98,22.92114501953125,721076.0,0.0,0.0
|
||||
2022-10-03 00:00:00+01:00,22.0,23.740000000000002,22.0,23.6,23.5395556640625,411048.0,0.0,0.0
|
||||
2022-10-04 00:00:00+01:00,23.14,24.82,23.14,24.48,24.4173046875,359955.0,0.0,0.0
|
||||
2022-10-05 00:00:00+01:00,24.6,24.6,23.38,23.66,23.599401855468752,787207.0,0.0,0.0
|
||||
2022-10-06 00:00:00+01:00,23.3,24.36,23.3,24.16,24.10596923828125,179826.0,0.77,0.0
|
||||
2022-10-07 00:00:00+01:00,24.32,24.32,23.12,23.28,23.22793701171875,182711.0,0.0,0.0
|
||||
2022-10-10 00:00:00+01:00,23.0,23.28,22.240000000000002,22.44,22.389814453125002,138462.0,0.0,0.0
|
||||
2022-10-11 00:00:00+01:00,22.38,22.72,22.1,22.18,22.1303955078125,148515.0,0.0,0.0
|
||||
2022-10-12 00:00:00+01:00,23.12,23.12,21.88,22.16,22.110439453125,162450.0,0.0,0.0
|
||||
2022-10-13 00:00:00+01:00,22.740000000000002,22.740000000000002,21.12,21.900000000000002,21.851022949218752,326778.0,0.0,0.0
|
||||
2022-10-14 00:00:00+01:00,22.0,22.76,21.82,22.5,22.44968017578125,161983.0,0.0,0.0
|
||||
2022-10-17 00:00:00+01:00,22.86,23.01260009765625,22.2,22.94,22.8886962890625,116551.0,0.0,0.0
|
||||
2022-10-18 00:00:00+01:00,22.26,23.38,22.26,23.12,23.06829345703125,141461.0,0.0,0.0
|
||||
2022-10-19 00:00:00+01:00,23.0,23.16,22.240000000000002,22.36,22.30999267578125,104562.0,0.0,0.0
|
||||
2022-10-20 00:00:00+01:00,22.38,22.72,21.82,22.5,22.44968017578125,152158.0,0.0,0.0
|
||||
2022-10-21 00:00:00+01:00,22.5,23.1,22.28,23.0,22.9485595703125,104972.0,0.0,0.0
|
||||
2022-10-24 00:00:00+01:00,23.02,23.900000000000002,23.0,23.38,23.3277099609375,159898.0,0.0,0.0
|
||||
2022-10-25 00:00:00+01:00,23.72,24.46,23.42,24.16,24.10596923828125,85381.0,0.0,0.0
|
||||
2022-10-26 00:00:00+01:00,24.16,24.2,23.66,24.14,24.0860107421875,117490.0,0.0,0.0
|
||||
2022-10-27 00:00:00+01:00,24.080000000000002,24.54,23.88,24.34,24.285566406250002,238792.0,0.0,0.0
|
||||
2022-10-28 00:00:00+01:00,24.1,24.22,23.719599609375,24.080000000000002,24.0261474609375,122712.0,0.0,0.0
|
||||
2022-10-31 00:00:00+00:00,24.26,24.46,23.66,24.1,24.04610107421875,102273.0,0.0,0.0
|
||||
2022-11-01 00:00:00+00:00,24.5,24.94,24.02,24.22,24.16583251953125,72028.0,0.0,0.0
|
||||
2022-11-02 00:00:00+00:00,24.1,25.0,23.92,24.64,24.584892578125,145464.0,0.0,0.0
|
||||
2022-11-03 00:00:00+00:00,24.28,24.72,23.88,24.04,23.9862353515625,73546.0,0.0,0.0
|
||||
2022-11-04 00:00:00+00:00,24.240000000000002,25.080000000000002,23.60639892578125,24.28,24.2256982421875,69077.0,0.0,0.0
|
||||
2022-11-07 00:00:00+00:00,24.22,25.080000000000002,24.02,24.900000000000002,24.8443115234375,124283.0,0.0,0.0
|
||||
2022-11-08 00:00:00+00:00,24.580000000000002,25.22,24.580000000000002,25.22,25.16359619140625,153287.0,0.0,0.0
|
||||
2022-11-09 00:00:00+00:00,24.98,25.22,24.88,24.98,24.92413330078125,100019.0,0.0,0.0
|
||||
2022-11-10 00:00:00+00:00,24.82,26.54,24.64,26.2,26.14140625,132777.0,0.0,0.0
|
||||
2022-11-11 00:00:00+00:00,26.36,26.86,26.16,26.580000000000002,26.52055419921875,219220.0,0.0,0.0
|
||||
2022-11-14 00:00:00+00:00,26.3,27.1,26.26,26.96,26.89970458984375,128692.0,0.0,0.0
|
||||
2022-11-15 00:00:00+00:00,26.48,27.16,26.14,26.92,26.859794921875,186824.0,0.0,0.0
|
||||
2022-11-16 00:00:00+00:00,27.02,27.04,26.38,26.52,26.4606884765625,107714.0,0.0,0.0
|
||||
2022-11-17 00:00:00+00:00,26.76,26.76,25.8,26.7,26.6402880859375,111413.0,0.0,0.0
|
||||
2022-11-18 00:00:00+00:00,26.88,27.1,26.32,27.1,27.03939208984375,127583.0,0.0,0.0
|
||||
2022-11-21 00:00:00+00:00,27.96,29.15199951171875,27.43699951171875,27.740000000000002,27.677958984375,517109.0,0.0,0.0
|
||||
2022-11-22 00:00:00+00:00,28.0,28.0,26.86,27.66,27.5981396484375,209083.0,0.0,0.0
|
||||
2022-11-23 00:00:00+00:00,27.6,28.34,27.5,28.34,28.27661865234375,458322.0,0.0,0.0
|
||||
2022-11-24 00:00:00+00:00,29.0,29.26,27.6,28.8,28.73558837890625,189652.0,0.0,0.0
|
||||
2022-11-25 00:00:00+00:00,28.400000000000002,29.03300048828125,28.400000000000002,28.900000000000002,28.8353662109375,146017.0,0.0,0.0
|
||||
2022-11-28 00:00:00+00:00,28.7,29.1,28.0,29.1,29.03491943359375,255817.0,0.0,0.0
|
||||
2022-11-29 00:00:00+00:00,29.080000000000002,29.14,28.8,28.900000000000002,28.8353662109375,204232.0,0.0,0.0
|
||||
2022-11-30 00:00:00+00:00,28.76,29.62,28.76,29.5,29.434023437500002,538520.0,0.0,0.0
|
||||
2022-12-01 00:00:00+00:00,29.68,29.900000000000002,29.060000000000002,29.76,29.69344482421875,188618.0,0.0,0.0
|
||||
2022-12-02 00:00:00+00:00,29.88,30.560000000000002,29.3,29.48,29.41406982421875,384388.0,0.0,0.0
|
||||
2022-12-05 00:00:00+00:00,29.36,29.92,28.26,28.28,28.2167529296875,225089.0,0.0,0.0
|
||||
2022-12-06 00:00:00+00:00,28.1,28.48,27.78,27.94,27.8775146484375,320011.0,0.0,0.0
|
||||
2022-12-07 00:00:00+00:00,27.92,28.2,27.64,27.94,27.8775146484375,341034.0,0.0,0.0
|
||||
2022-12-08 00:00:00+00:00,27.78,28.080000000000002,27.72,27.92,27.85756103515625,219670.0,0.0,0.0
|
||||
2022-12-09 00:00:00+00:00,27.400000000000002,28.0,27.400000000000002,28.0,27.937380371093752,138547.0,0.0,0.0
|
||||
2022-12-12 00:00:00+00:00,28.400000000000002,28.76300048828125,27.72,28.240000000000002,28.17684326171875,128168.0,0.0,0.0
|
||||
2022-12-13 00:00:00+00:00,28.34,29.1,27.86,28.38,28.316530761718752,263580.0,0.0,0.0
|
||||
2022-12-14 00:00:00+00:00,28.0,28.36,27.86,28.22,28.15688720703125,62627.0,0.0,0.0
|
||||
2022-12-15 00:00:00+00:00,27.900000000000002,28.18,27.54,27.54,27.478408203125,256065.0,0.0,0.0
|
||||
2022-12-16 00:00:00+00:00,27.5,27.96,27.080000000000002,27.400000000000002,27.33872314453125,147966.0,0.0,0.0
|
||||
2022-12-19 00:00:00+00:00,27.52,27.9739990234375,27.38,27.52,27.4584521484375,62241.0,0.0,0.0
|
||||
2022-12-20 00:00:00+00:00,27.5,27.62,26.8,27.38,27.31876708984375,116737.0,0.0,0.0
|
||||
2022-12-21 00:00:00+00:00,27.64,28.1,27.24030029296875,27.86,27.79769287109375,47330.0,0.0,0.0
|
||||
2022-12-22 00:00:00+00:00,27.86,28.26,27.3,27.48,27.418544921875,59975.0,0.0,0.0
|
||||
2022-12-23 00:00:00+00:00,28.26,28.26,27.240000000000002,27.46,27.3985888671875,37424.0,0.0,0.0
|
||||
2022-12-28 00:00:00+00:00,27.44,27.7,27.22,27.42,27.3586767578125,39217.0,0.0,0.0
|
||||
2022-12-29 00:00:00+00:00,27.04,27.66,27.02,27.62,27.558229980468752,96876.0,0.0,0.0
|
||||
2022-12-30 00:00:00+00:00,26.96,27.66,26.96,27.240000000000002,27.179079589843752,23796.0,0.0,0.0
|
||||
2023-01-03 00:00:00+00:00,27.2,28.22,26.64,27.66,27.5981396484375,68033.0,0.0,0.0
|
||||
2023-01-04 00:00:00+00:00,27.54,27.98,27.1572998046875,27.88,27.81764892578125,68241.0,0.0,0.0
|
||||
2023-01-05 00:00:00+00:00,27.76,28.3,27.562900390625,28.04,27.9772900390625,99643.0,0.0,0.0
|
||||
2023-01-06 00:00:00+00:00,27.68,28.72,27.68,28.6,28.5360400390625,132308.0,0.0,0.0
|
||||
2023-01-09 00:00:00+00:00,27.0,28.72,26.529279785156252,28.0,27.937380371093752,144894.0,0.0,0.0
|
||||
2023-01-10 00:00:00+00:00,29.0,29.0,27.42,27.560000000000002,27.498361816406252,108914.0,0.0,0.0
|
||||
2023-01-11 00:00:00+00:00,28.8,28.8,27.36,28.32,28.2566650390625,117605.0,0.0,0.0
|
||||
2023-01-12 00:00:00+00:00,28.0,28.16,26.67,26.98,26.919658203125,394851.0,0.0,0.0
|
||||
2023-01-13 00:00:00+00:00,26.76,27.0839990234375,25.400000000000002,25.6,25.54274658203125,356966.0,0.0,0.0
|
||||
2023-01-16 00:00:00+00:00,25.0,26.080000000000002,24.86,25.18,25.1236865234375,336471.0,0.0,0.0
|
||||
2023-01-17 00:00:00+00:00,25.22,25.400000000000002,24.92,25.3,25.24341552734375,221386.0,0.0,0.0
|
||||
2023-01-18 00:00:00+00:00,25.66,26.78,25.37659912109375,26.240000000000002,26.181318359375002,1025972.0,0.0,0.0
|
||||
2023-01-19 00:00:00+00:00,27.0,27.0,25.98,26.62,26.56046630859375,102617.0,0.0,0.0
|
||||
2023-01-20 00:00:00+00:00,26.72,27.0,26.34,26.44,26.38086669921875,192758.0,0.0,0.0
|
||||
2023-01-23 00:00:00+00:00,26.48,26.650000000000002,25.86,26.12,26.06158447265625,159375.0,0.0,0.0
|
||||
2023-01-24 00:00:00+00:00,26.3,26.44,25.88,26.060000000000002,26.001718750000002,285494.0,0.0,0.0
|
||||
2023-01-25 00:00:00+00:00,26.5,28.04,26.18,27.740000000000002,27.677958984375,379047.0,0.0,0.0
|
||||
2023-01-26 00:00:00+00:00,27.86,28.26,27.66,27.740000000000002,27.677958984375,234863.0,0.0,0.0
|
||||
2023-01-27 00:00:00+00:00,27.900000000000002,28.48,27.44,28.44,28.37639404296875,96625.0,0.0,0.0
|
||||
2023-01-30 00:00:00+00:00,28.14,28.68,27.88,28.16,28.097021484375002,169732.0,0.0,0.0
|
||||
2023-01-31 00:00:00+00:00,28.060000000000002,28.400000000000002,27.84,28.400000000000002,28.336484375,250688.0,0.0,0.0
|
||||
2023-02-01 00:00:00+00:00,28.2,28.72,27.400000000000002,28.34,28.27661865234375,97416.0,0.0,0.0
|
||||
2023-02-02 00:00:00+00:00,28.68,29.560000000000002,28.1,29.2,29.13469482421875,245261.0,0.0,0.0
|
||||
2023-02-03 00:00:00+00:00,29.66,29.7,28.8,29.28,29.214514160156252,211695.0,0.0,0.0
|
||||
2023-02-06 00:00:00+00:00,29.02,29.48,28.92597900390625,29.04,28.9750537109375,78978.0,0.0,0.0
|
||||
2023-02-07 00:00:00+00:00,28.2,28.98,27.7,28.26,28.196796875,327488.0,0.0,0.0
|
||||
2023-02-08 00:00:00+00:00,28.7,28.7,28.0,28.36,28.296572265625002,88715.0,0.0,0.0
|
||||
2023-02-09 00:00:00+00:00,29.0,29.0,28.44,28.7,28.635812988281252,113023.0,0.0,0.0
|
||||
2023-02-10 00:00:00+00:00,28.8,28.89,28.02,28.02,27.95733642578125,169490.0,0.0,0.0
|
||||
2023-02-13 00:00:00+00:00,27.900000000000002,28.38,27.36,28.38,28.316530761718752,140602.0,0.0,0.0
|
||||
2023-02-14 00:00:00+00:00,27.060000000000002,28.560000000000002,27.060000000000002,28.0,27.937380371093752,107333.0,0.0,0.0
|
||||
2023-02-15 00:00:00+00:00,28.18,28.900000000000002,27.724599609375,28.84,28.77550048828125,129853.0,0.0,0.0
|
||||
2023-02-16 00:00:00+00:00,27.3,29.240000000000002,27.3,29.12,29.05487548828125,63977.0,0.0,0.0
|
||||
2023-02-17 00:00:00+00:00,29.96,29.96,28.5,28.5,28.436262207031252,75842.0,0.0,0.0
|
||||
2023-02-20 00:00:00+00:00,28.400000000000002,28.92,28.3,28.900000000000002,28.8353662109375,44533.0,0.0,0.0
|
||||
2023-02-21 00:00:00+00:00,28.580000000000002,29.14,28.580000000000002,28.8,28.73558837890625,176561.0,0.0,0.0
|
||||
2023-02-22 00:00:00+00:00,28.900000000000002,28.900000000000002,28.48,28.76,28.695681152343752,146264.0,0.0,0.0
|
||||
2023-02-23 00:00:00+00:00,28.82,29.34,28.66,28.88,28.81541015625,86655.0,0.0,0.0
|
||||
2023-02-24 00:00:00+00:00,28.98,28.98,28.240000000000002,28.42,28.3564404296875,69783.0,0.0,0.0
|
||||
2023-02-27 00:00:00+00:00,28.68,29.060000000000002,28.1,28.84,28.77550048828125,78772.0,0.0,0.0
|
||||
2023-02-28 00:00:00+00:00,28.62,29.1,28.580000000000002,28.92,28.855322265625002,386853.0,0.0,0.0
|
||||
2023-03-01 00:00:00+00:00,28.92,29.72,28.86,29.36,29.2943359375,106416.0,0.0,0.0
|
||||
2023-03-02 00:00:00+00:00,29.8,29.82,28.92,29.62,29.55375732421875,60874.0,0.0,0.0
|
||||
2023-03-03 00:00:00+00:00,29.8,29.92,29.22,29.44,29.37416015625,59389.0,0.0,0.0
|
||||
2023-03-06 00:00:00+00:00,29.46,29.54,29.02,29.240000000000002,29.17460693359375,68220.0,0.0,0.0
|
||||
2023-03-07 00:00:00+00:00,28.5,29.6,28.5,29.400000000000002,29.334248046875,69588.0,0.0,0.0
|
||||
2023-03-08 00:00:00+00:00,28.92,29.900000000000002,28.68280029296875,29.64,29.5737109375,57394.0,0.0,0.0
|
||||
2023-03-09 00:00:00+00:00,29.400000000000002,30.0,29.283999023437502,29.92,29.8530859375,85081.0,0.0,0.0
|
||||
2023-03-10 00:00:00+00:00,30.0,30.0,29.0,29.560000000000002,29.4938916015625,121079.0,0.0,0.0
|
||||
2023-03-13 00:00:00+00:00,29.26,29.48,28.48,28.48,28.41630615234375,451156.0,0.0,0.0
|
||||
2023-03-14 00:00:00+00:00,28.5,29.02,28.28,29.02,28.95509765625,173562.0,0.0,0.0
|
||||
2023-03-15 00:00:00+00:00,28.900000000000002,28.9418505859375,25.46,26.46,26.4008251953125,646146.0,0.0,0.0
|
||||
2023-03-16 00:00:00+00:00,26.14,26.88,26.14,26.48,26.420778808593752,240692.0,0.0,0.0
|
||||
2023-03-17 00:00:00+00:00,26.72,27.580000000000002,26.42,26.42,26.3609130859375,145813.0,0.0,0.0
|
||||
2023-03-20 00:00:00+00:00,26.02,27.28,25.82,26.88,26.81988525390625,156224.0,0.0,0.0
|
||||
2023-03-21 00:00:00+00:00,27.12,27.26,26.6,27.2,27.13916748046875,101085.0,0.0,0.0
|
||||
2023-03-22 00:00:00+00:00,27.04,27.28,26.68,27.060000000000002,26.99947998046875,61646.0,0.0,0.0
|
||||
2023-03-23 00:00:00+00:00,27.46,27.84,27.0,27.76,27.69791748046875,238904.0,0.0,0.0
|
||||
2023-03-24 00:00:00+00:00,27.66,27.8639990234375,27.18,27.7,27.6380517578125,151064.0,0.0,0.0
|
||||
2023-03-27 00:00:00+01:00,27.98,28.14,27.0,27.060000000000002,26.99947998046875,242115.0,0.0,0.0
|
||||
2023-03-28 00:00:00+01:00,27.12,27.12,26.34,26.6,26.540510253906252,162045.0,0.0,0.0
|
||||
2023-03-29 00:00:00+01:00,26.64,27.46,26.38,27.240000000000002,27.179079589843752,219929.0,0.0,0.0
|
||||
2023-03-30 00:00:00+01:00,27.76,29.080000000000002,27.650000000000002,28.080000000000002,28.0172021484375,285091.0,0.0,0.0
|
||||
2023-03-31 00:00:00+01:00,28.1,28.14,27.400000000000002,27.580000000000002,27.51831787109375,143041.0,0.0,0.0
|
||||
2023-04-03 00:00:00+01:00,27.580000000000002,27.580000000000002,27.14,27.26,27.19903564453125,100038.0,0.0,0.0
|
||||
2023-04-04 00:00:00+01:00,27.14,27.5535400390625,27.04,27.14,27.0793017578125,89315.0,0.0,0.0
|
||||
2023-04-05 00:00:00+01:00,27.6,27.8,25.48,25.5,25.44297119140625,174325.0,0.0,0.0
|
||||
2023-04-06 00:00:00+01:00,25.6,26.03199951171875,25.46,26.0,25.94185302734375,163437.0,0.0,0.0
|
||||
2023-04-11 00:00:00+01:00,26.0,26.580000000000002,25.86,26.22,26.161359863281252,148621.0,0.0,0.0
|
||||
2023-04-12 00:00:00+01:00,26.68,27.0,26.02,26.64,26.58042236328125,118071.0,0.0,0.0
|
||||
2023-04-13 00:00:00+01:00,26.96,27.400000000000002,26.68,27.18,27.1192138671875,338659.0,0.0,0.0
|
||||
2023-04-14 00:00:00+01:00,27.5,27.86,26.72,26.72,26.66024169921875,188709.0,0.0,0.0
|
||||
2023-04-17 00:00:00+01:00,26.78,27.060000000000002,26.0356005859375,26.98,26.919658203125,260010.0,0.0,0.0
|
||||
2023-04-18 00:00:00+01:00,28.0,28.0,26.86,27.2,27.13916748046875,110566.0,0.0,0.0
|
||||
2023-04-19 00:00:00+01:00,26.8,27.38,26.72,27.240000000000002,27.179079589843752,238055.0,0.0,0.0
|
||||
2023-04-20 00:00:00+01:00,27.78,27.78,26.66,26.66,26.6003759765625,136925.0,0.0,0.0
|
||||
2023-04-21 00:00:00+01:00,26.5,27.400000000000002,26.48,27.02,26.959570312500002,102818.0,0.0,0.0
|
||||
2023-04-24 00:00:00+01:00,26.400000000000002,27.36,26.400000000000002,27.0,26.93961669921875,53770.0,0.0,0.0
|
||||
2023-04-25 00:00:00+01:00,26.78,27.34,26.7,26.96,26.89970458984375,584252.0,0.0,0.0
|
||||
2023-04-26 00:00:00+01:00,26.78,26.82,26.32,26.64,26.58042236328125,82215.0,0.0,0.0
|
||||
2023-04-27 00:00:00+01:00,26.14,26.78,26.14,26.76,26.70015380859375,72994.0,0.0,0.0
|
||||
2023-04-28 00:00:00+01:00,27.18,27.18,26.62,27.0,26.93961669921875,63114.0,0.0,0.0
|
||||
2023-05-02 00:00:00+01:00,26.400000000000002,27.095419921875,26.34,26.34,26.28109130859375,142978.0,0.0,0.0
|
||||
2023-05-03 00:00:00+01:00,26.42,26.5,24.96,25.1,25.043867187500002,350646.0,0.0,0.0
|
||||
2023-05-04 00:00:00+01:00,25.0,25.080000000000002,22.68,22.68,22.62927734375,1493890.0,0.0,0.0
|
||||
2023-05-05 00:00:00+01:00,22.6,22.7,21.92,22.0,21.95079833984375,582476.0,0.0,0.0
|
||||
2023-05-09 00:00:00+01:00,22.5,22.84,21.75010009765625,22.5,22.44968017578125,529565.0,0.0,0.0
|
||||
2023-05-10 00:00:00+01:00,22.5,22.8,21.78,21.8,21.7512451171875,315844.0,0.0,0.0
|
||||
2023-05-11 00:00:00+01:00,21.7,23.38,21.7,23.06,23.008427734375,489035.0,0.0,0.0
|
||||
2023-05-12 00:00:00+01:00,23.34,23.38,22.72,23.38,23.3277099609375,283610.0,0.0,0.0
|
||||
2023-05-15 00:00:00+01:00,23.04,23.62,23.04,23.5,23.44744384765625,388932.0,0.0,0.0
|
||||
2023-05-16 00:00:00+01:00,23.36,23.54,23.02,23.3,23.247890625,395998.0,0.0,0.0
|
||||
2023-05-17 00:00:00+01:00,23.56,23.580000000000002,22.68,22.84,22.78891845703125,423318.0,0.0,0.0
|
||||
2023-05-18 00:00:00+01:00,22.96,23.240000000000002,22.42,22.72,22.669189453125,319457.0,0.0,0.0
|
||||
2023-05-19 00:00:00+01:00,22.5,22.9019091796875,22.04,22.46,22.40976806640625,421569.0,0.0,0.0
|
||||
2023-05-22 00:00:00+01:00,22.78,22.84,22.38,22.8,22.7490087890625,166747.0,0.0,0.0
|
||||
2023-05-23 00:00:00+01:00,23.2,23.22,22.38,22.38,22.3299462890625,309329.0,0.0,0.0
|
||||
2023-05-24 00:00:00+01:00,22.02,22.33969970703125,20.56,20.94,20.893171386718752,512827.0,0.0,0.0
|
||||
2023-05-25 00:00:00+01:00,20.52,21.0,20.32,20.32,20.2745556640625,729567.0,0.0,0.0
|
||||
2023-05-26 00:00:00+01:00,20.88,20.88,19.72,19.78,19.735762939453124,492367.0,0.0,0.0
|
||||
2023-05-30 00:00:00+01:00,19.92,20.0152001953125,19.35,19.41,19.366590576171877,690501.0,0.0,0.0
|
||||
2023-05-31 00:00:00+01:00,20.2,20.2,19.19,19.45,19.40650146484375,317942.0,0.0,0.0
|
||||
2023-06-01 00:00:00+01:00,19.66,19.740000000000002,19.150000000000002,19.47,19.442449951171877,304732.0,1.6,0.0
|
||||
2023-06-02 00:00:00+01:00,20.22,20.22,19.37,19.82,19.79195556640625,278304.0,0.0,0.0
|
||||
2023-06-05 00:00:00+01:00,19.62,19.72,17.92,18.17,18.14428955078125,461315.0,0.0,0.0
|
||||
2023-06-06 00:00:00+01:00,18.07,18.18,17.29,17.45,17.425308837890626,828912.0,0.0,0.0
|
||||
2023-06-07 00:00:00+01:00,17.73,18.41,17.73,18.32,18.294077148437502,554274.0,0.0,0.0
|
||||
2023-06-08 00:00:00+01:00,17.61,18.6747998046875,17.61,18.22,18.19421875,270247.0,0.0,0.0
|
||||
2023-06-09 00:00:00+01:00,18.330000000000002,18.63,17.93,18.52,18.493795166015627,341997.0,0.0,0.0
|
||||
2023-06-12 00:00:00+01:00,18.19,19.12,18.143199462890625,19.12,19.0929443359375,357760.0,0.0,0.0
|
||||
2023-06-13 00:00:00+01:00,19.2,19.77,18.94,19.400000000000002,19.372548828125,648503.0,0.0,0.0
|
||||
2023-06-14 00:00:00+01:00,19.740000000000002,19.92,19.27,19.6,19.572266845703126,362355.0,0.0,0.0
|
||||
2023-06-15 00:00:00+01:00,19.6,19.775000000000002,18.96,19.18,19.152860107421876,437837.0,0.0,0.0
|
||||
2023-06-16 00:00:00+01:00,19.87,19.87,19.065,19.41,19.3825341796875,635867.0,0.0,0.0
|
||||
2023-06-19 00:00:00+01:00,19.37,19.37,18.93,18.95,18.92318603515625,343892.0,0.0,0.0
|
||||
2023-06-20 00:00:00+01:00,19.39,19.39,18.61,18.67,18.64358154296875,240994.0,0.0,0.0
|
||||
2023-06-21 00:00:00+01:00,19.45,19.469520263671875,18.36,18.91,18.8832421875,276880.0,0.0,0.0
|
||||
2023-06-22 00:00:00+01:00,18.95,19.162230224609374,18.37,18.8,18.7733984375,186330.0,0.0,0.0
|
||||
2023-06-23 00:00:00+01:00,18.6,19.04,18.6,18.87,18.843298339843752,189003.0,0.0,0.0
|
||||
2023-06-26 00:00:00+01:00,19.0,19.04719970703125,18.32,18.57,18.543724365234375,411820.0,0.0,0.0
|
||||
2023-06-27 00:00:00+01:00,18.650000000000002,18.77,17.669100341796874,18.03,18.004488525390624,538190.0,0.0,0.0
|
||||
2023-06-28 00:00:00+01:00,18.0,18.2,17.92,18.2,18.174246826171874,210732.0,0.0,0.0
|
||||
2023-06-29 00:00:00+01:00,18.7,18.7,17.54,17.59,17.56510986328125,253575.0,0.0,0.0
|
||||
2023-06-30 00:00:00+01:00,17.67,18.11,17.43,18.1,18.074388427734377,150826.0,0.0,0.0
|
||||
2023-07-03 00:00:00+01:00,17.900000000000002,18.36,17.88,18.330000000000002,18.3040625,791780.0,0.0,0.0
|
||||
2023-07-04 00:00:00+01:00,18.400000000000002,18.522430419921875,18.12,18.42,18.393935546875,287173.0,0.0,0.0
|
||||
2023-07-05 00:00:00+01:00,18.56,18.580000000000002,18.255999755859374,18.36,18.334019775390626,160679.0,0.0,0.0
|
||||
2023-07-06 00:00:00+01:00,18.5,18.54,17.240000000000002,17.51,17.485223388671876,281127.0,0.0,0.0
|
||||
2023-07-07 00:00:00+01:00,17.51,17.51,16.69,17.1,17.07580322265625,290241.0,0.0,0.0
|
||||
2023-07-10 00:00:00+01:00,17.240000000000002,17.77,16.87,16.95,16.926015625,339775.0,0.0,0.0
|
||||
2023-07-11 00:00:00+01:00,17.5,17.5,16.12,16.14,16.117161865234376,371758.0,0.0,0.0
|
||||
2023-07-12 00:00:00+01:00,16.15,17.14,16.12,16.88,16.856114501953126,494734.0,0.0,0.0
|
||||
2023-07-13 00:00:00+01:00,17.0,17.330000000000002,16.85,16.89,16.86610107421875,155535.0,0.0,0.0
|
||||
2023-07-14 00:00:00+01:00,16.8,17.55,16.62,17.12,17.095775146484375,208870.0,0.0,0.0
|
||||
2023-07-17 00:00:00+01:00,17.0,17.17,16.740000000000002,16.9,16.87608642578125,155692.0,0.0,0.0
|
||||
2023-07-18 00:00:00+01:00,17.72,17.72,16.64,16.68,16.656397705078124,132785.0,0.0,0.0
|
||||
2023-07-19 00:00:00+01:00,17.1,17.62,16.87530029296875,17.62,17.595067138671876,396633.0,0.0,0.0
|
||||
2023-07-20 00:00:00+01:00,17.82,17.97,17.59,17.63,17.6050537109375,372626.0,0.0,0.0
|
||||
2023-07-21 00:00:00+01:00,17.86,18.063800048828124,17.6,17.88,17.85469970703125,257740.0,0.0,0.0
|
||||
2023-07-24 00:00:00+01:00,17.6,18.041500244140625,17.48,17.71,17.684940185546875,360104.0,0.0,0.0
|
||||
2023-07-25 00:00:00+01:00,17.740000000000002,18.22,17.57154052734375,17.86,17.834727783203125,209875.0,0.0,0.0
|
||||
2023-07-26 00:00:00+01:00,17.77,18.13,17.71,17.78,17.754842529296877,282136.0,0.0,0.0
|
||||
2023-07-27 00:00:00+01:00,17.78,18.19,17.7,18.06,18.034444580078127,198157.0,0.0,0.0
|
||||
2023-07-28 00:00:00+01:00,18.25,18.25,17.900000000000002,18.0,17.974530029296876,134365.0,0.0,0.0
|
||||
2023-07-31 00:00:00+01:00,17.990000000000002,18.0,17.448499755859377,17.62,17.595067138671876,266973.0,0.0,0.0
|
||||
2023-08-01 00:00:00+01:00,17.44,17.44,14.77,15.8,15.777642822265625,1707985.0,0.0,0.0
|
||||
2023-08-02 00:00:00+01:00,15.700000000000001,16.15,15.700000000000001,15.860000000000001,15.83755859375,597276.0,0.0,0.0
|
||||
2023-08-03 00:00:00+01:00,15.700000000000001,15.875,15.56,15.66,15.637841796875,720097.0,0.0,0.0
|
||||
2023-08-04 00:00:00+01:00,15.89,15.89,15.2875,15.450000000000001,15.428138427734375,130835.0,0.0,0.0
|
||||
2023-08-07 00:00:00+01:00,15.23,15.73,14.88,14.98,14.9588037109375,133228.0,0.0,0.0
|
||||
2023-08-08 00:00:00+01:00,14.8,15.18,14.65,14.93,14.908873291015626,187614.0,0.0,0.0
|
||||
2023-08-09 00:00:00+01:00,15.72,15.9,14.955999755859375,15.06,15.038690185546875,384876.0,0.0,0.0
|
||||
2023-08-10 00:00:00+01:00,15.06,15.11,14.450000000000001,14.5,14.479482421875,509873.0,0.0,0.0
|
||||
2023-08-11 00:00:00+01:00,15.0,15.07,14.6,14.75,14.72912841796875,498841.0,0.0,0.0
|
||||
2023-08-14 00:00:00+01:00,14.75,15.32,14.75,15.11,15.088619384765625,202173.0,0.0,0.0
|
||||
2023-08-15 00:00:00+01:00,15.120000000000001,15.18,14.68,14.84,14.819001464843751,167723.0,0.0,0.0
|
||||
2023-08-16 00:00:00+01:00,14.89,15.08,14.51,14.790000000000001,14.769072265625,172976.0,0.0,0.0
|
||||
2023-08-17 00:00:00+01:00,14.790000000000001,15.32,14.47,14.950000000000001,14.92884521484375,145057.0,0.0,0.0
|
||||
2023-08-18 00:00:00+01:00,14.4,14.96,14.4,14.85,14.828988037109376,246954.0,0.0,0.0
|
||||
2023-08-21 00:00:00+01:00,15.16,15.16,14.73,14.85,14.828988037109376,208997.0,0.0,0.0
|
||||
2023-08-22 00:00:00+01:00,14.82,15.17,14.75,14.85,14.828988037109376,89056.0,0.0,0.0
|
||||
2023-08-23 00:00:00+01:00,14.56,15.05,14.56,14.71,14.6891845703125,494801.0,0.0,0.0
|
||||
2023-08-24 00:00:00+01:00,14.98,14.993909912109375,14.71,14.71,14.6891845703125,102654.0,0.0,0.0
|
||||
2023-08-25 00:00:00+01:00,15.44,15.44,14.700000000000001,14.77,14.749100341796876,136975.0,0.0,0.0
|
||||
2023-08-29 00:00:00+01:00,14.96,15.52,14.85,15.49,15.4680810546875,146752.0,0.0,0.0
|
||||
2023-08-30 00:00:00+01:00,15.49,15.624000244140625,15.18,15.38,15.358237304687501,259486.0,0.0,0.0
|
||||
2023-08-31 00:00:00+01:00,15.35,15.51,15.18,15.25,15.228421630859375,312027.0,0.0,0.0
|
||||
2023-09-01 00:00:00+01:00,15.38,15.41,14.950000000000001,14.99,14.9687890625,122627.0,0.0,0.0
|
||||
2023-09-04 00:00:00+01:00,14.99,15.1,14.83,14.83,14.80901611328125,138450.0,0.0,0.0
|
||||
2023-09-05 00:00:00+01:00,14.8,14.83199951171875,14.42,14.66,14.63925537109375,173206.0,0.0,0.0
|
||||
2023-09-06 00:00:00+01:00,15.0,15.040000000000001,14.44,14.81,14.789044189453126,194887.0,0.0,0.0
|
||||
2023-09-07 00:00:00+01:00,14.83,15.6,14.46,15.530000000000001,15.50802490234375,243553.0,0.0,0.0
|
||||
2023-09-08 00:00:00+01:00,15.0,15.89,15.0,15.89,15.867515869140625,339473.0,0.0,0.0
|
||||
2023-09-11 00:00:00+01:00,16.22,16.32,14.68,14.73,14.709156494140625,274162.0,0.0,0.0
|
||||
2023-09-12 00:00:00+01:00,14.4,14.55,12.620000000000001,14.05,14.03011962890625,695308.0,0.0,0.0
|
||||
2023-09-13 00:00:00+01:00,14.09,15.47,13.790000000000001,15.44,15.41815185546875,359608.0,0.0,0.0
|
||||
2023-09-14 00:00:00+01:00,15.5,16.126199951171877,15.5,16.07,16.0472607421875,818615.0,0.0,0.0
|
||||
2023-09-15 00:00:00+01:00,16.31,16.32,15.57,15.63,15.607884521484376,470826.0,0.0,0.0
|
||||
2023-09-18 00:00:00+01:00,15.44,15.85,15.169410400390625,15.22,15.198463134765625,388020.0,0.0,0.0
|
||||
2023-09-19 00:00:00+01:00,15.11,15.58,14.9039599609375,15.32,15.29832275390625,244500.0,0.0,0.0
|
||||
2023-09-20 00:00:00+01:00,15.44,16.02,15.44,15.88,15.857530517578125,260949.0,0.0,0.0
|
||||
2023-09-21 00:00:00+01:00,15.610000000000001,15.83,15.0,15.19,15.168505859375001,380456.0,0.0,0.0
|
||||
2023-09-22 00:00:00+01:00,15.1,15.48,15.1,15.35,15.328280029296875,144967.0,0.0,0.0
|
||||
2023-09-25 00:00:00+01:00,15.35,15.6,14.960999755859376,15.19,15.168505859375001,326513.0,0.0,0.0
|
||||
2023-09-26 00:00:00+01:00,15.58,15.58,14.58,14.63,14.609298095703124,139051.0,0.0,0.0
|
||||
2023-09-27 00:00:00+01:00,14.58,15.34,14.48,15.13,15.10859130859375,140879.0,0.0,0.0
|
||||
2023-09-28 00:00:00+01:00,15.120000000000001,15.19,14.83,15.0,14.9787744140625,345116.0,0.0,0.0
|
||||
2023-09-29 00:00:00+01:00,15.0,15.610000000000001,15.0,15.47,15.448109130859375,256397.0,0.0,0.0
|
||||
2023-10-02 00:00:00+01:00,15.46,15.67,14.870000000000001,15.040000000000001,15.01871826171875,291241.0,0.0,0.0
|
||||
2023-10-03 00:00:00+01:00,14.71,14.89,14.0,14.05,14.03011962890625,179006.0,0.0,0.0
|
||||
2023-10-04 00:00:00+01:00,13.83,14.290000000000001,13.77,13.81,13.790458984375,237634.0,0.0,0.0
|
||||
2023-10-05 00:00:00+01:00,13.92,14.17,13.85,13.85,13.838919677734376,180284.0,0.85,0.0
|
||||
2023-10-06 00:00:00+01:00,14.450000000000001,14.450000000000001,13.55,13.99,13.978807373046875,116485.0,0.0,0.0
|
||||
2023-10-09 00:00:00+01:00,13.52,14.030000000000001,13.41,13.620000000000001,13.60910400390625,136545.0,0.0,0.0
|
||||
2023-10-10 00:00:00+01:00,13.89,14.55,13.72,14.55,14.538359375,245926.0,0.0,0.0
|
||||
2023-10-11 00:00:00+01:00,14.32,14.52,13.450000000000001,13.52,13.509183349609375,134243.0,0.0,0.0
|
||||
2023-10-12 00:00:00+01:00,14.0,14.0,13.38,13.51,13.49919189453125,112363.0,0.0,0.0
|
||||
2023-10-13 00:00:00+01:00,13.46,13.75,13.1,13.1,13.089520263671876,264982.0,0.0,0.0
|
||||
2023-10-16 00:00:00+01:00,13.1,13.42699951171875,12.69,13.31,13.299351806640626,142869.0,0.0,0.0
|
||||
2023-10-17 00:00:00+01:00,13.21,13.479949951171875,13.09300048828125,13.370000000000001,13.35930419921875,103846.0,0.0,0.0
|
||||
2023-10-18 00:00:00+01:00,13.5,13.5,12.69,12.75,12.7397998046875,586500.0,0.0,0.0
|
||||
2023-10-19 00:00:00+01:00,12.52,13.213499755859376,12.52,13.11,13.09951171875,200672.0,0.0,0.0
|
||||
2023-10-20 00:00:00+01:00,13.07,13.41,12.83,13.18,13.169455566406251,592696.0,0.0,0.0
|
||||
2023-10-23 00:00:00+01:00,13.25,13.4,13.0,13.33,13.3193359375,121413.0,0.0,0.0
|
||||
2023-10-24 00:00:00+01:00,13.42,13.64,13.0,13.1,13.089520263671876,173527.0,0.0,0.0
|
||||
2023-10-25 00:00:00+01:00,13.09,13.34,12.96,13.14,13.129487304687501,113657.0,0.0,0.0
|
||||
2023-10-26 00:00:00+01:00,13.0,13.280000000000001,12.96,13.1,13.089520263671876,162088.0,0.0,0.0
|
||||
2023-10-27 00:00:00+01:00,13.1,13.16,12.85,13.0,12.989599609375,172121.0,0.0,0.0
|
||||
2023-10-30 00:00:00+00:00,13.09,13.200000000000001,12.99,13.06,13.049552001953126,351486.0,0.0,0.0
|
||||
2023-10-31 00:00:00+00:00,13.01,13.3,13.0,13.05,13.039559326171876,380834.0,0.0,0.0
|
||||
2023-11-01 00:00:00+00:00,12.950000000000001,13.120000000000001,12.77843994140625,13.02,13.009583740234376,199402.0,0.0,0.0
|
||||
2023-11-02 00:00:00+00:00,13.1,13.46,13.040000000000001,13.34,13.329327392578126,414055.0,0.0,0.0
|
||||
2023-11-03 00:00:00+00:00,13.6,14.415000000000001,13.52384033203125,14.0,13.988800048828125,348357.0,0.0,0.0
|
||||
2023-11-06 00:00:00+00:00,14.13,14.48,13.530000000000001,13.66,13.649072265625,95127.0,0.0,0.0
|
||||
2023-11-07 00:00:00+00:00,13.5,13.93,13.5,13.84,13.82892822265625,164937.0,0.0,0.0
|
||||
2023-11-08 00:00:00+00:00,13.74,14.0456005859375,13.69,13.8,13.7889599609375,275526.0,0.0,0.0
|
||||
2023-11-09 00:00:00+00:00,13.950000000000001,14.19,13.71550048828125,13.85,13.838919677734376,308199.0,0.0,0.0
|
||||
2023-11-10 00:00:00+00:00,13.73,13.834399414062501,13.22,13.620000000000001,13.60910400390625,211940.0,0.0,0.0
|
||||
2023-11-13 00:00:00+00:00,13.5,13.72,13.4,13.55,13.53916015625,206951.0,0.0,0.0
|
||||
2023-11-14 00:00:00+00:00,13.5,14.41,13.42,14.14,14.128687744140626,714971.0,0.0,0.0
|
||||
2023-11-15 00:00:00+00:00,14.290000000000001,14.99,14.030000000000001,14.52,14.508383789062501,430958.0,0.0,0.0
|
||||
2023-11-16 00:00:00+00:00,14.08,14.505,14.08,14.23,14.218615722656251,193252.0,0.0,0.0
|
||||
2023-11-17 00:00:00+00:00,14.11,14.99,14.11,14.82,14.808143310546875,474070.0,0.0,0.0
|
||||
2023-11-20 00:00:00+00:00,14.77,15.120000000000001,14.77,14.98,14.968016357421876,127160.0,0.0,0.0
|
||||
2023-11-21 00:00:00+00:00,14.98,15.31,14.85,14.88,14.868095703125,312023.0,0.0,0.0
|
||||
2023-11-22 00:00:00+00:00,14.84,15.19,14.8,14.94,14.928048095703126,93813.0,0.0,0.0
|
||||
2023-11-23 00:00:00+00:00,14.96,15.055,14.67,14.88,14.868095703125,89248.0,0.0,0.0
|
||||
2023-11-24 00:00:00+00:00,14.76,14.9,14.67,14.85,14.8381201171875,118893.0,0.0,0.0
|
||||
2023-11-27 00:00:00+00:00,14.530000000000001,14.86,13.98,13.98,13.968815917968751,129900.0,0.0,0.0
|
||||
2023-11-28 00:00:00+00:00,13.84,14.14,13.19,13.34,13.329327392578126,377366.0,0.0,0.0
|
||||
2023-11-29 00:00:00+00:00,13.200000000000001,14.35,13.200000000000001,13.950000000000001,13.93884033203125,471577.0,0.0,0.0
|
||||
2023-11-30 00:00:00+00:00,13.8,14.11800048828125,13.44,13.68,13.669056396484375,348127.0,0.0,0.0
|
||||
2023-12-01 00:00:00+00:00,13.700000000000001,13.84,13.576400146484374,13.73,13.719016113281251,352771.0,0.0,0.0
|
||||
2023-12-04 00:00:00+00:00,14.0,14.0,13.120000000000001,13.16,13.149471435546875,104065.0,0.0,0.0
|
||||
2023-12-05 00:00:00+00:00,13.07,13.200000000000001,12.6,13.0,12.989599609375,303748.0,0.0,0.0
|
||||
2023-12-06 00:00:00+00:00,12.9,13.26,12.9,13.02,13.009583740234376,681974.0,0.0,0.0
|
||||
2023-12-07 00:00:00+00:00,13.4,13.4,12.56,12.82,12.80974365234375,193151.0,0.0,0.0
|
||||
2023-12-08 00:00:00+00:00,12.85,12.98,12.64,12.76,12.749791259765626,169002.0,0.0,0.0
|
||||
2023-12-11 00:00:00+00:00,12.700000000000001,13.530000000000001,12.700000000000001,13.36,13.3493115234375,316496.0,0.0,0.0
|
||||
2023-12-12 00:00:00+00:00,13.33,13.36,12.948399658203126,13.26,13.24939208984375,279752.0,0.0,0.0
|
||||
2023-12-13 00:00:00+00:00,13.4,13.48,13.16,13.41,13.399271240234375,223452.0,0.0,0.0
|
||||
2023-12-14 00:00:00+00:00,13.8,14.59,13.74,14.3,14.2885595703125,258358.0,0.0,0.0
|
||||
2023-12-15 00:00:00+00:00,13.71,14.31,13.71,14.13,14.1186962890625,433550.0,0.0,0.0
|
||||
2023-12-18 00:00:00+00:00,14.38,15.33740966796875,13.89,15.290000000000001,15.277767333984375,256957.0,0.0,0.0
|
||||
2023-12-19 00:00:00+00:00,15.290000000000001,15.700000000000001,15.040000000000001,15.46,15.4476318359375,152997.0,0.0,0.0
|
||||
2023-12-20 00:00:00+00:00,15.75,15.92,15.33,15.83,15.817335205078125,258981.0,0.0,0.0
|
||||
2023-12-21 00:00:00+00:00,15.73,16.03,15.34,16.02,16.007183837890626,160788.0,0.0,0.0
|
||||
2023-12-22 00:00:00+00:00,16.0,16.543089599609374,15.73,16.35,16.336920166015624,183509.0,0.0,0.0
|
||||
2023-12-27 00:00:00+00:00,16.1,16.95,16.0,16.69,16.67664794921875,332319.0,0.0,0.0
|
||||
2023-12-28 00:00:00+00:00,16.29,16.95,16.0,16.6,16.586719970703125,129658.0,0.0,0.0
|
||||
2023-12-29 00:00:00+00:00,16.66,16.77678955078125,16.606290283203126,16.62,16.6067041015625,54474.0,0.0,0.0
|
||||
2024-01-02 00:00:00+00:00,16.9,16.93,15.950000000000001,15.98,15.967215576171876,433331.0,0.0,0.0
|
||||
2024-01-03 00:00:00+00:00,16.45,16.45,15.583499755859375,15.8,15.787359619140625,212305.0,0.0,0.0
|
||||
2024-01-04 00:00:00+00:00,16.18,16.2,15.32,15.5,15.48760009765625,145849.0,0.0,0.0
|
||||
2024-01-05 00:00:00+00:00,15.43,15.63,14.84,15.34,15.327728271484375,178331.0,0.0,0.0
|
||||
2024-01-08 00:00:00+00:00,15.200000000000001,15.88,15.08,15.3,15.287760009765625,93619.0,0.0,0.0
|
||||
2024-01-09 00:00:00+00:00,15.450000000000001,15.32,15.21,15.280000000000001,15.26777587890625,236053.0,0.0,0.0
|
||||
2024-01-10 00:00:00+00:00,15.21,15.51,15.120000000000001,15.16,15.147872314453124,203338.0,0.0,0.0
|
||||
2024-01-11 00:00:00+00:00,15.21,15.44,14.73,14.73,14.71821533203125,128350.0,0.0,0.0
|
||||
2024-01-12 00:00:00+00:00,14.81,15.3,14.81,15.280000000000001,15.26777587890625,126422.0,0.0,0.0
|
||||
2024-01-15 00:00:00+00:00,15.085,15.32,14.86,14.86,14.848111572265625,86831.0,0.0,0.0
|
||||
2024-01-16 00:00:00+00:00,15.08,15.66,14.91,15.39,15.37768798828125,253055.0,0.0,0.0
|
||||
2024-01-17 00:00:00+00:00,15.040000000000001,15.5,14.450000000000001,14.540000000000001,14.528367919921875,114336.0,0.0,0.0
|
||||
2024-01-18 00:00:00+00:00,14.9,15.22,14.59,15.22,15.207823486328126,175262.0,0.0,0.0
|
||||
2024-01-19 00:00:00+00:00,15.450000000000001,15.450000000000001,14.89,14.89,14.87808837890625,93241.0,0.0,0.0
|
||||
2024-01-22 00:00:00+00:00,15.11,15.15,14.835,15.05,15.037960205078125,92117.0,0.0,0.0
|
||||
2024-01-23 00:00:00+00:00,14.51,15.63,14.51,15.3,15.287760009765625,96389.0,0.0,0.0
|
||||
2024-01-24 00:00:00+00:00,15.530000000000001,15.74,15.200000000000001,15.74,15.7274072265625,278489.0,0.0,0.0
|
||||
2024-01-25 00:00:00+00:00,15.32,15.84550048828125,15.030000000000001,15.55,15.537559814453125,476735.0,0.0,0.0
|
||||
2024-01-26 00:00:00+00:00,15.66,16.11,15.26,15.99,15.977208251953126,417225.0,0.0,0.0
|
||||
2024-01-29 00:00:00+00:00,15.91,16.240000000000002,15.69,16.240000000000002,16.227008056640624,112434.0,0.0,0.0
|
||||
2024-01-30 00:00:00+00:00,16.1,16.740000000000002,16.080000000000002,16.65,16.6366796875,156730.0,0.0,0.0
|
||||
2024-01-31 00:00:00+00:00,15.99,16.84,15.99,16.6,16.586719970703125,249055.0,0.0,0.0
|
||||
2024-02-01 00:00:00+00:00,16.55,16.89,16.44,16.78,16.766575927734376,230759.0,0.0,0.0
|
||||
2024-02-02 00:00:00+00:00,16.69,17.0,16.46,16.46,16.446832275390626,170565.0,0.0,0.0
|
||||
2024-02-05 00:00:00+00:00,16.26,16.79,16.175,16.31,16.296951904296876,130266.0,0.0,0.0
|
||||
2024-02-06 00:00:00+00:00,16.4,17.07,16.38,16.78,16.766575927734376,391036.0,0.0,0.0
|
||||
2024-02-07 00:00:00+00:00,16.7,17.16,16.55,17.09,17.076328125,215847.0,0.0,0.0
|
||||
2024-02-08 00:00:00+00:00,17.150000000000002,17.91,17.150000000000002,17.44,17.42604736328125,450151.0,0.0,0.0
|
||||
2024-02-09 00:00:00+00:00,17.46,17.80198974609375,17.07,17.18,17.166256103515625,242803.0,0.0,0.0
|
||||
2024-02-12 00:00:00+00:00,17.25,17.84,16.96,16.990000000000002,16.976407470703126,563881.0,0.0,0.0
|
||||
2024-02-13 00:00:00+00:00,16.85,16.885140380859376,16.330000000000002,16.51,16.4967919921875,68119.0,0.0,0.0
|
||||
2024-02-14 00:00:00+00:00,16.37,17.17,16.18530029296875,17.03,17.016375732421874,98220.0,0.0,0.0
|
||||
2024-02-15 00:00:00+00:00,16.51,17.39,16.51,16.96,16.946431884765627,102797.0,0.0,0.0
|
||||
2024-02-16 00:00:00+00:00,16.990000000000002,17.330000000000002,16.990000000000002,17.07,17.056343994140626,47249.0,0.0,0.0
|
||||
2024-02-19 00:00:00+00:00,17.07,17.271500244140626,16.82,17.14,17.126287841796877,465791.0,0.0,0.0
|
||||
2024-02-20 00:00:00+00:00,17.0,17.0,16.12,16.12,16.107103271484377,117840.0,0.0,0.0
|
||||
2024-02-21 00:00:00+00:00,16.44,16.52,16.09,16.18,16.1670556640625,616655.0,0.0,0.0
|
||||
2024-02-22 00:00:00+00:00,15.99,16.69,15.5,16.59,16.576727294921874,71029.0,0.0,0.0
|
||||
2024-02-23 00:00:00+00:00,16.61,16.66,15.9,16.2,16.187039794921876,616927.0,0.0,0.0
|
||||
2024-02-26 00:00:00+00:00,15.9,16.24449951171875,15.56,15.700000000000001,15.687440185546876,125089.0,0.0,0.0
|
||||
2024-02-27 00:00:00+00:00,15.5,15.88,15.34,15.57,15.557543945312501,506414.0,0.0,0.0
|
||||
2024-02-28 00:00:00+00:00,15.0,15.6,13.540000000000001,14.46,14.448431396484375,1617451.0,0.0,0.0
|
||||
2024-02-29 00:00:00+00:00,14.700000000000001,14.99,14.27,14.34,14.32852783203125,131744.0,0.0,0.0
|
||||
2024-03-01 00:00:00+00:00,14.52,14.83,14.0,14.68,14.668255615234376,710016.0,0.0,0.0
|
||||
2024-03-04 00:00:00+00:00,14.3,14.790000000000001,14.3,14.450000000000001,14.43843994140625,128631.0,0.0,0.0
|
||||
2024-03-05 00:00:00+00:00,14.43,14.5,14.13,14.3,14.2885595703125,226847.0,0.0,0.0
|
||||
2024-03-06 00:00:00+00:00,14.35,14.6,14.13,14.13,14.1186962890625,245345.0,0.0,0.0
|
||||
2024-03-07 00:00:00+00:00,14.36,14.36,13.55,13.55,13.53916015625,169908.0,0.0,0.0
|
||||
2024-03-08 00:00:00+00:00,13.55,13.84,13.26,13.3,13.2893603515625,591778.0,0.0,0.0
|
||||
2024-03-11 00:00:00+00:00,13.450000000000001,13.6,13.15,13.25,13.2393994140625,537344.0,0.0,0.0
|
||||
2024-03-12 00:00:00+00:00,13.0,13.74,13.0,13.700000000000001,13.689039306640625,652597.0,0.0,0.0
|
||||
2024-03-13 00:00:00+00:00,14.5,15.65,13.521639404296875,13.72,13.7090234375,1195682.0,0.0,0.0
|
||||
2024-03-14 00:00:00+00:00,13.82,14.59,13.34,14.32,14.308543701171875,1126694.0,0.0,0.0
|
||||
2024-03-15 00:00:00+00:00,14.3,14.56,14.02,14.26,14.24859130859375,1525658.0,0.0,0.0
|
||||
2024-03-18 00:00:00+00:00,14.34,14.620000000000001,14.02,14.24,14.228608398437501,462513.0,0.0,0.0
|
||||
2024-03-19 00:00:00+00:00,14.24,14.48,13.81,13.81,13.798951416015626,496898.0,0.0,0.0
|
||||
2024-03-20 00:00:00+00:00,13.83,14.02,12.780000000000001,13.33,13.3193359375,340715.0,0.0,0.0
|
||||
2024-03-21 00:00:00+00:00,13.48,13.809000244140625,13.23,13.34,13.329327392578126,276189.0,0.0,0.0
|
||||
2024-03-22 00:00:00+00:00,13.44,13.58,13.120000000000001,13.13,13.119495849609375,477630.0,0.0,0.0
|
||||
2024-03-25 00:00:00+00:00,13.5,13.5,12.64,12.64,12.629887695312501,437124.0,0.0,0.0
|
||||
2024-03-26 00:00:00+00:00,12.64,13.0,12.410699462890625,12.56,12.549952392578126,1102700.0,0.0,0.0
|
||||
2024-03-27 00:00:00+00:00,12.5,12.77,12.38,12.58,12.569935302734375,1158042.0,0.0,0.0
|
||||
2024-03-28 00:00:00+00:00,12.68,13.32,12.455,13.02,13.009583740234376,672275.0,0.0,0.0
|
||||
2024-04-02 00:00:00+01:00,12.9,13.13,12.38,12.46,12.45003173828125,420287.0,0.0,0.0
|
||||
2024-04-03 00:00:00+01:00,12.280000000000001,12.49,11.99,12.22,12.210223388671876,460217.0,0.0,0.0
|
||||
2024-04-04 00:00:00+01:00,12.200000000000001,12.17,12.0,12.0,11.990400390625,293870.0,0.0,0.0
|
||||
2024-04-05 00:00:00+01:00,11.98,12.037879638671875,11.6,11.65,11.640679931640625,395059.0,0.0,0.0
|
||||
2024-04-08 00:00:00+01:00,11.61,12.120000000000001,11.495000000000001,12.06,12.0503515625,810772.0,0.0,0.0
|
||||
2024-04-09 00:00:00+01:00,12.0,12.15,11.790000000000001,11.91,11.900472412109375,413918.0,0.0,0.0
|
||||
2024-04-10 00:00:00+01:00,11.950000000000001,12.33,11.8725,12.01,12.000391845703126,680979.0,0.0,0.0
|
||||
2024-04-11 00:00:00+01:00,12.08,12.31,11.868509521484375,11.94,11.930447998046875,280220.0,0.0,0.0
|
||||
2024-04-12 00:00:00+01:00,12.06,12.290000000000001,11.4,11.450000000000001,11.44083984375,359653.0,0.0,0.0
|
||||
2024-04-15 00:00:00+01:00,11.41,11.57,11.01,11.4,11.390880126953125,489256.0,0.0,0.0
|
||||
2024-04-16 00:00:00+01:00,11.200000000000001,11.78,11.07,11.51,11.500792236328126,294117.0,0.0,0.0
|
||||
2024-04-17 00:00:00+01:00,11.5,11.81050048828125,11.4,11.620000000000001,11.610704345703125,446216.0,0.0,0.0
|
||||
2024-04-18 00:00:00+01:00,11.43,11.83,11.43,11.71,11.70063232421875,280345.0,0.0,0.0
|
||||
2024-04-19 00:00:00+01:00,11.8,11.8,11.56,11.68,11.670655517578124,187448.0,0.0,0.0
|
||||
2024-04-22 00:00:00+01:00,11.5,12.06,11.5,11.72,11.710623779296876,233273.0,0.0,0.0
|
||||
2024-04-23 00:00:00+01:00,11.870000000000001,11.89,11.72,11.72,11.710623779296876,164436.0,0.0,0.0
|
||||
2024-04-24 00:00:00+01:00,12.08,12.08,11.370000000000001,11.51,11.500792236328126,185184.0,0.0,0.0
|
||||
2024-04-25 00:00:00+01:00,11.700000000000001,11.700000000000001,11.1,11.36,11.350911865234375,295818.0,0.0,0.0
|
||||
2024-04-26 00:00:00+01:00,11.31,11.64,11.230880126953124,11.39,11.380887451171875,144819.0,0.0,0.0
|
||||
2024-04-29 00:00:00+01:00,11.15,11.82,11.15,11.82,11.81054443359375,119071.0,0.0,0.0
|
||||
2024-04-30 00:00:00+01:00,11.98,11.99,11.42,11.5,11.490799560546876,199939.0,0.0,0.0
|
||||
2024-05-01 00:00:00+01:00,12.01,12.01,11.32,11.59,11.5807275390625,165171.0,0.0,0.0
|
||||
2024-05-02 00:00:00+01:00,11.57,11.66,11.3,11.66,11.65067138671875,305855.0,0.0,0.0
|
||||
2024-05-03 00:00:00+01:00,11.85,11.96,11.6,11.75,11.740599365234376,158727.0,0.0,0.0
|
||||
2024-05-07 00:00:00+01:00,12.13,12.19,11.57,11.790000000000001,11.780567626953125,116963.0,0.0,0.0
|
||||
2024-05-08 00:00:00+01:00,12.15,12.804000244140624,11.99,12.67,12.65986328125,362985.0,0.0,0.0
|
||||
2024-05-09 00:00:00+01:00,12.65,12.71,12.18,12.66,12.649871826171875,261229.0,0.0,0.0
|
||||
2024-05-10 00:00:00+01:00,12.47,12.97,12.47,12.89,12.879687500000001,187666.0,0.0,0.0
|
||||
2024-05-13 00:00:00+01:00,12.8,13.120000000000001,12.58,12.8,12.789759521484376,164449.0,0.0,0.0
|
||||
2024-05-14 00:00:00+01:00,12.6,13.237950439453126,12.6,13.08,13.0695361328125,166908.0,0.0,0.0
|
||||
2024-05-15 00:00:00+01:00,13.36,13.48,13.030000000000001,13.450000000000001,13.439239501953125,178857.0,0.0,0.0
|
||||
2024-05-16 00:00:00+01:00,13.450000000000001,14.0,13.450000000000001,14.0,13.988800048828125,314200.0,0.0,0.0
|
||||
2024-05-17 00:00:00+01:00,14.13,14.8,13.780000000000001,14.700000000000001,14.68823974609375,558689.0,0.0,0.0
|
||||
2024-05-20 00:00:00+01:00,24.5,24.98,22.82,22.82,22.8017431640625,8292215.0,0.0,0.0
|
||||
2024-05-21 00:00:00+01:00,23.02,23.44,22.400000000000002,22.56,22.54195068359375,1407097.0,0.0,0.0
|
||||
2024-05-22 00:00:00+01:00,22.46,22.64,22.0,22.0,21.98239990234375,723017.0,0.0,0.0
|
||||
2024-05-23 00:00:00+01:00,21.98,22.47597900390625,21.62,22.3,22.3,1522184.0,1.76,0.0
|
||||
2024-05-24 00:00:00+01:00,22.240000000000002,22.3,21.68,22.14,22.14,644971.0,0.0,0.0
|
||||
2024-05-28 00:00:00+01:00,22.2,22.6,22.06,22.5,22.5,311246.0,0.0,0.0
|
||||
2024-05-29 00:00:00+01:00,22.48,22.6010009765625,22.16,22.3,22.3,1482854.0,0.0,0.0
|
||||
2024-05-30 00:00:00+01:00,22.5,22.62,22.3,22.32,22.32,138373.0,0.0,0.0
|
||||
2024-05-31 00:00:00+01:00,22.0,22.48,22.0,22.34,22.34,695505.0,0.0,0.0
|
||||
2024-06-03 00:00:00+01:00,22.2,22.48,22.1,22.36,22.36,148218.0,0.0,0.0
|
||||
2024-06-04 00:00:00+01:00,22.36,22.36,21.75,22.0,22.0,1289764.0,0.0,0.0
|
||||
2024-06-05 00:00:00+01:00,22.36,22.36,21.8,22.02,22.02,295325.0,0.0,0.0
|
||||
2024-06-06 00:00:00+01:00,22.02,22.145700683593752,21.78,22.04,22.04,463598.0,0.0,0.0
|
||||
2024-06-07 00:00:00+01:00,22.1,22.2,21.740000000000002,21.98,21.98,799873.0,0.0,0.0
|
||||
2024-06-10 00:00:00+01:00,21.900000000000002,22.02,21.64,21.64,21.64,588812.0,0.0,0.0
|
||||
2024-06-11 00:00:00+01:00,21.84,22.1,21.400000000000002,21.42,21.42,323278.0,0.0,0.0
|
||||
2024-06-12 00:00:00+01:00,21.72,21.72,21.2,21.5,21.5,961776.0,0.0,0.0
|
||||
2024-06-13 00:00:00+01:00,21.7,21.7,21.0,21.36,21.36,731949.0,0.0,0.0
|
||||
2024-06-14 00:00:00+01:00,21.72,22.62,21.435,22.62,22.62,1564845.0,0.0,0.0
|
||||
2024-06-17 00:00:00+01:00,22.42,22.60555908203125,22.05300048828125,22.3,22.3,543001.0,0.0,0.0
|
||||
2024-06-18 00:00:00+01:00,22.5,22.5,22.011999511718752,22.28,22.28,302283.0,0.0,0.0
|
||||
2024-06-19 00:00:00+01:00,22.0,22.36,21.94,22.0,22.0,261639.0,0.0,0.0
|
||||
2024-06-20 00:00:00+01:00,22.5,22.5,21.900000000000002,22.400000000000002,22.400000000000002,298140.0,0.0,0.0
|
||||
2024-06-21 00:00:00+01:00,22.5,22.900000000000002,22.22,22.38,22.38,374718.0,0.0,0.0
|
||||
2024-06-24 00:00:00+01:00,22.400000000000002,22.62,22.2,22.38,22.38,182607.0,0.0,0.0
|
||||
2024-06-25 00:00:00+01:00,22.3,22.32,21.32049072265625,21.92,21.92,1156786.0,0.0,0.0
|
||||
2024-06-26 00:00:00+01:00,22.0,22.0,21.44,21.740000000000002,21.740000000000002,1321707.0,0.0,0.0
|
||||
2024-06-27 00:00:00+01:00,21.86,21.92,21.6,21.78,21.78,1192605.0,0.0,0.0
|
||||
2024-06-28 00:00:00+01:00,23.1,23.21093994140625,22.88800048828125,23.12,23.12,5166863.0,0.0,0.0
|
||||
2024-07-01 00:00:00+01:00,23.26,23.26,23.06,23.080000000000002,23.080000000000002,904708.0,0.0,0.0
|
||||
2024-07-02 00:00:00+01:00,23.080000000000002,23.240000000000002,23.06,23.18,23.18,800296.0,0.0,0.0
|
||||
2024-07-03 00:00:00+01:00,23.84,23.900000000000002,23.78333984375,23.900000000000002,23.900000000000002,8961383.0,0.0,0.0
|
||||
2024-07-04 00:00:00+01:00,23.92,23.94,23.83340087890625,23.86,23.86,1175939.0,0.0,0.0
|
||||
2024-07-05 00:00:00+01:00,23.900000000000002,23.96,23.86,23.88,23.88,969052.0,0.0,0.0
|
||||
2024-07-08 00:00:00+01:00,23.88,24.060000000000002,23.88,23.88,23.88,420214.0,0.0,0.0
|
||||
2024-07-09 00:00:00+01:00,23.92,23.96,23.86,23.900000000000002,23.900000000000002,1264139.0,0.0,0.0
|
||||
2024-07-10 00:00:00+01:00,23.88,23.94,23.88,23.900000000000002,23.900000000000002,371085.0,0.0,0.0
|
||||
2024-07-11 00:00:00+01:00,23.84,23.92,23.82,23.82,23.82,458586.0,0.0,0.0
|
||||
2024-07-12 00:00:00+01:00,23.82,23.88,23.82,23.88,23.88,681277.0,0.0,0.0
|
||||
2024-07-15 00:00:00+01:00,23.84,23.88,23.84,23.86,23.86,739304.0,0.0,0.0
|
||||
2024-07-16 00:00:00+01:00,23.88,23.883859863281252,23.84,23.86,23.86,1130090.0,0.0,0.0
|
||||
2024-07-17 00:00:00+01:00,23.88,23.88,23.86,23.86,23.86,755831.0,0.0,0.0
|
||||
2024-07-18 00:00:00+01:00,23.88,23.900000000000002,23.86,23.900000000000002,23.900000000000002,960170.0,0.0,0.0
|
||||
2024-07-19 00:00:00+01:00,23.900000000000002,23.94,23.86,23.94,23.94,195271.0,0.0,0.0
|
||||
2024-07-22 00:00:00+01:00,23.88,23.92,23.8,23.84,23.84,3036352.0,0.0,0.0
|
||||
2024-07-23 00:00:00+01:00,23.82,23.86,23.8,23.82,23.82,1083480.0,0.0,0.0
|
||||
2024-07-24 00:00:00+01:00,23.84,23.88,23.8,23.8,23.8,1445489.0,0.0,0.0
|
||||
2024-07-25 00:00:00+01:00,23.84,23.900000000000002,23.8,23.8,23.8,582850.0,0.0,0.0
|
||||
2024-07-26 00:00:00+01:00,23.96,23.96,23.8,23.8,23.8,675264.0,0.0,0.0
|
||||
2024-07-29 00:00:00+01:00,23.84,23.88,23.5783203125,23.84,23.84,1403210.0,0.0,0.0
|
||||
2024-07-30 00:00:00+01:00,23.84,23.88,23.82,23.84,23.84,1286201.0,0.0,0.0
|
||||
2024-07-31 00:00:00+01:00,23.86,23.88,23.82,23.88,23.88,308556.0,0.0,0.0
|
||||
2024-08-01 00:00:00+01:00,23.900000000000002,23.900000000000002,23.84,23.84,23.84,139383.0,0.0,0.0
|
||||
2024-08-02 00:00:00+01:00,24.2,24.2,23.84,23.84,23.84,402227.0,0.0,0.0
|
||||
2024-08-05 00:00:00+01:00,23.84,23.88,23.8,23.88,23.88,2543161.0,0.0,0.0
|
||||
2024-08-06 00:00:00+01:00,23.900000000000002,24.060000000000002,23.82,23.88,23.88,805371.0,0.0,0.0
|
||||
2024-08-07 00:00:00+01:00,23.900000000000002,23.92,23.84,23.86,23.86,1753790.0,0.0,0.0
|
||||
2024-08-08 00:00:00+01:00,23.86,23.92,23.86,23.88,23.88,191998.0,0.0,0.0
|
||||
2024-08-09 00:00:00+01:00,23.900000000000002,23.98,23.86,23.98,23.98,289215.0,0.0,0.0
|
||||
2024-08-12 00:00:00+01:00,23.96,24.0,23.92,24.0,24.0,513766.0,0.0,0.0
|
||||
2024-08-13 00:00:00+01:00,24.0,24.04,23.94,24.04,24.04,185320.0,0.0,0.0
|
||||
2024-08-14 00:00:00+01:00,24.0,24.3,23.96,24.3,24.3,300442.0,0.0,0.0
|
||||
2024-08-15 00:00:00+01:00,24.1,24.12,24.0,24.02,24.02,222740.0,0.0,0.0
|
||||
2024-08-16 00:00:00+01:00,24.1,24.1,23.98,23.98,23.98,255770.0,0.0,0.0
|
||||
2024-08-19 00:00:00+01:00,24.080000000000002,24.080000000000002,23.96,24.0,24.0,229725.0,0.0,0.0
|
||||
2024-08-20 00:00:00+01:00,24.0,24.04,23.98,24.0,24.0,261084.0,0.0,0.0
|
||||
2024-08-21 00:00:00+01:00,24.080000000000002,24.080000000000002,23.98,24.060000000000002,24.060000000000002,1086506.0,0.0,0.0
|
||||
2024-08-22 00:00:00+01:00,24.080000000000002,24.080000000000002,24.02,24.060000000000002,24.060000000000002,163317.0,0.0,0.0
|
||||
2024-08-23 00:00:00+01:00,24.080000000000002,24.080000000000002,24.0,24.080000000000002,24.080000000000002,202364.0,0.0,0.0
|
||||
2024-08-27 00:00:00+01:00,24.060000000000002,24.18,24.02,24.060000000000002,24.060000000000002,245203.0,0.0,0.0
|
||||
2024-08-28 00:00:00+01:00,24.02,24.12,24.02,24.04,24.04,349423.0,0.0,0.0
|
||||
2024-08-29 00:00:00+01:00,24.04,24.12,24.04,24.060000000000002,24.060000000000002,187436.0,0.0,0.0
|
||||
2024-08-30 00:00:00+01:00,24.16,24.3,24.02,24.26,24.26,1493472.0,0.0,0.0
|
||||
2024-09-02 00:00:00+01:00,24.240000000000002,24.28,24.22,24.240000000000002,24.240000000000002,397048.0,0.0,0.0
|
||||
2024-09-03 00:00:00+01:00,24.240000000000002,24.28,24.22,24.22,24.22,526456.0,0.0,0.0
|
||||
2024-09-04 00:00:00+01:00,24.240000000000002,24.33919921875,24.22,24.240000000000002,24.240000000000002,830622.0,0.0,0.0
|
||||
2024-09-05 00:00:00+01:00,24.26,24.28,24.240000000000002,24.240000000000002,24.240000000000002,2561655.0,0.0,0.0
|
||||
2024-09-06 00:00:00+01:00,24.240000000000002,24.3,24.240000000000002,24.240000000000002,24.240000000000002,2621382.0,0.0,0.0
|
||||
2024-09-09 00:00:00+01:00,24.240000000000002,24.333601074218752,24.240000000000002,24.26,24.26,946993.0,0.0,0.0
|
||||
2024-09-10 00:00:00+01:00,24.28,24.38,24.240000000000002,24.28,24.28,1955248.0,0.0,0.0
|
||||
2024-09-11 00:00:00+01:00,24.28,24.3,24.255720214843752,24.26,24.26,3357431.0,0.0,0.0
|
||||
2024-09-12 00:00:00+01:00,24.28,24.32,24.26,24.3,24.3,1396090.0,0.0,0.0
|
||||
2024-09-13 00:00:00+01:00,24.26,24.3,24.26,24.26,24.26,539753.0,0.0,0.0
|
||||
2024-09-16 00:00:00+01:00,24.28,24.3,24.26,24.28,24.28,3548116.0,0.0,0.0
|
||||
2024-09-17 00:00:00+01:00,24.3,24.3143994140625,24.28,24.28,24.28,6116775.0,0.0,0.0
|
||||
2024-09-18 00:00:00+01:00,24.28,24.3,24.26,24.28,24.28,1315109.0,0.0,0.0
|
||||
2024-09-19 00:00:00+01:00,24.28,24.307199707031252,24.28,24.28,24.28,3447049.0,0.0,0.0
|
||||
2024-09-20 00:00:00+01:00,24.28,24.301000976562502,24.28,24.3,24.3,949712.0,0.0,0.0
|
||||
2024-09-23 00:00:00+01:00,24.3,24.34,24.28,24.28,24.28,1165867.0,0.0,0.0
|
||||
2024-09-24 00:00:00+01:00,24.3,24.34,24.29,24.3,24.3,417334.0,0.0,0.0
|
||||
2024-09-25 00:00:00+01:00,24.32,24.356000976562502,24.28,24.32,24.32,1311755.0,0.0,0.0
|
||||
2024-09-26 00:00:00+01:00,24.3,24.36,24.3,24.32,24.32,2165924.0,0.0,0.0
|
||||
2024-09-27 00:00:00+01:00,24.34,24.385,24.32,24.34,24.34,191057.0,0.0,0.0
|
||||
2024-09-30 00:00:00+01:00,24.36,24.36,24.3,24.36,24.36,418219.0,0.0,0.0
|
||||
2024-10-01 00:00:00+01:00,24.36,24.38,24.34,24.34,24.34,834978.0,0.0,0.0
|
||||
2024-10-02 00:00:00+01:00,24.34,24.38,24.34,24.36,24.36,321113.0,0.0,0.0
|
||||
2024-10-03 00:00:00+01:00,24.36,24.400000000000002,24.36,24.36,24.36,119311.0,0.0,0.0
|
||||
2024-10-04 00:00:00+01:00,24.400000000000002,24.400000000000002,24.355380859375,24.38,24.38,408506.0,0.0,0.0
|
||||
2024-10-07 00:00:00+01:00,24.400000000000002,24.400000000000002,24.36,24.400000000000002,24.400000000000002,934866.0,0.0,0.0
|
||||
2024-10-08 00:00:00+01:00,24.38,24.400000000000002,24.36,24.38,24.38,351909.0,0.0,0.0
|
||||
2024-10-09 00:00:00+01:00,24.400000000000002,24.400000000000002,24.36,24.36,24.36,373356.0,0.0,0.0
|
||||
2024-10-10 00:00:00+01:00,24.36,24.400000000000002,24.36,24.38,24.38,566301.0,0.0,0.0
|
||||
2024-10-11 00:00:00+01:00,24.400000000000002,24.400000000000002,24.36,24.38,24.38,88197.0,0.0,0.0
|
||||
2024-10-14 00:00:00+01:00,24.42,24.42,24.36,24.36,24.36,2859472.0,0.0,0.0
|
||||
2024-10-15 00:00:00+01:00,24.38,24.42,24.38,24.400000000000002,24.400000000000002,1387949.0,0.0,0.0
|
||||
2024-10-16 00:00:00+01:00,24.42,24.42,24.38,24.38,24.38,518018.0,0.0,0.0
|
||||
2024-10-17 00:00:00+01:00,24.42,24.42,24.378291015625,24.38,24.38,1199504.0,0.0,0.0
|
||||
2024-10-18 00:00:00+01:00,24.400000000000002,24.52,24.38,24.400000000000002,24.400000000000002,612904.0,0.0,0.0
|
||||
2024-10-21 00:00:00+01:00,24.42,24.46,24.42,24.44,24.44,937999.0,0.0,0.0
|
||||
2024-10-22 00:00:00+01:00,24.46,24.48,24.44,24.46,24.46,9890907.0,0.0,0.0
|
||||
2024-10-23 00:00:00+01:00,24.46,24.46,24.46,24.46,24.46,0.0,0.0,0.0
|
||||
2024-10-24 00:00:00+01:00,,,,,,,0.0,0.0
|
||||
2024-10-25 00:00:00+01:00,,,,,,,0.0,0.0
|
||||
2024-10-28 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-10-29 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-10-30 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-10-31 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-01 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-04 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-05 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-06 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-07 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-08 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-11 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-12 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-13 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
2024-11-14 00:00:00+00:00,,,,,,,0.0,0.0
|
||||
|
@@ -1,741 +0,0 @@
|
||||
Datetime,Open,High,Low,Close,Adj Close,Volume,Dividends,Stock Splits,Repaired?
|
||||
2022-01-03 00:00:00+01:00,20.400468826293945,20.80828094482422,20.400468826293945,20.629241943359375,20.04158073767676,559352,0.0,0.0,True
|
||||
2022-01-04 00:00:00+01:00,20.649133682250977,20.897798538208008,20.5098819732666,20.848066329956055,20.254170979989347,930594,0.0,0.0,True
|
||||
2022-01-05 00:00:00+01:00,20.897798538208008,21.126571655273438,20.838119506835938,21.126571655273438,20.524743211692808,572100,0.0,0.0,True
|
||||
2022-01-06 00:00:00+01:00,20.887853622436523,21.126571655273438,20.599401473999023,20.967424392700195,20.37013149695311,532086,0.0,0.0,True
|
||||
2022-01-07 00:00:00+01:00,21.007211685180664,21.186250686645508,20.867958068847656,21.126571655273438,20.524743211692808,698666,0.0,0.0,True
|
||||
2022-01-10 00:00:00+01:00,21.186250686645508,21.245929718017578,20.997264862060547,21.05694580078125,20.457101019221444,972438,0.0,0.0,True
|
||||
2022-01-11 00:00:00+01:00,21.226036071777344,21.514488220214844,21.226036071777344,21.37523651123047,20.766324448700836,894602,0.0,0.0,True
|
||||
2022-01-12 00:00:00+01:00,21.564220428466797,21.604007720947266,21.0469970703125,21.216089248657227,20.611711003052147,838352,0.0,0.0,True
|
||||
2022-01-13 00:00:00+01:00,20.897798538208008,21.14646339416504,20.897798538208008,21.14646339416504,20.558603716304646,514241,0.015,0.0,True
|
||||
2022-01-14 00:00:00+01:00,20.897798538208008,21.066890716552734,20.80828094482422,21.0271053314209,20.442562606650853,708327,0.0,0.0,True
|
||||
2022-01-17 00:00:00+01:00,21.106678009033203,21.633846282958984,21.0469970703125,21.554275512695312,20.95507670278679,947841,0.0,0.0,True
|
||||
2022-01-18 00:00:00+01:00,21.454809188842773,21.484647750854492,21.156410217285156,21.405075073242188,20.81002451088455,966355,0.0,0.0,True
|
||||
2022-01-19 00:00:00+01:00,21.37523651123047,21.822832107543945,21.295663833618164,21.78304672241211,21.177492853798224,1597827,0.0,0.0,True
|
||||
2022-01-20 00:00:00+01:00,21.802940368652344,22.111284255981445,21.544328689575195,21.981977462768555,21.370893093551224,1563328,0.0,0.0,True
|
||||
2022-01-21 00:00:00+01:00,21.74325942993164,21.94219207763672,21.415021896362305,21.65374183654785,21.051780846838273,1539782,0.0,0.0,True
|
||||
2022-01-24 00:00:00+01:00,21.484647750854492,21.58411407470703,20.887853622436523,20.997264862060547,20.413553134072398,1334240,0.0,0.0,True
|
||||
2022-01-25 00:00:00+01:00,21.156410217285156,21.186250686645508,20.877906799316406,20.917692184448242,20.336192394303197,1198631,0.0,0.0,True
|
||||
2022-01-26 00:00:00+01:00,20.997264862060547,21.72336769104004,20.997264862060547,21.415021896362305,20.819697017860687,913216,0.0,0.0,True
|
||||
2022-01-27 00:00:00+01:00,21.11662483215332,21.862619400024414,21.0469970703125,21.6437931060791,21.04210673019215,765306,0.0,0.0,True
|
||||
2022-01-28 00:00:00+01:00,21.554275512695312,21.65374183654785,21.126571655273438,21.484647750854492,20.887385250653754,1109097,0.0,0.0,True
|
||||
2022-01-31 00:00:00+01:00,21.6239013671875,21.65374183654785,21.066890716552734,21.186250686645508,20.597285695859238,999557,0.0,0.0,True
|
||||
2022-02-01 00:00:00+01:00,21.27577018737793,21.405075073242188,21.05694580078125,21.11662483215332,20.529594243726194,732572,0.0,0.0,True
|
||||
2022-02-02 00:00:00+01:00,21.52443504333496,22.021764755249023,21.454809188842773,21.753206253051758,21.1484769425398,1195479,0.0,0.0,True
|
||||
2022-02-03 00:00:00+01:00,21.773099899291992,21.892459869384766,21.6239013671875,21.773099899291992,21.167820346822086,906159,0.0,0.0,True
|
||||
2022-02-04 00:00:00+01:00,21.87256622314453,21.87256622314453,21.345396041870117,21.424968719482422,20.829366305496844,763864,0.0,0.0,True
|
||||
2022-02-07 00:00:00+01:00,21.574167251586914,21.574167251586914,21.265823364257812,21.415021896362305,20.819697017860687,382854,0.0,0.0,True
|
||||
2022-02-08 00:00:00+01:00,21.36528968811035,21.78304672241211,21.36528968811035,21.713420867919922,21.109798182325196,1006721,0.0,0.0,True
|
||||
2022-02-09 00:00:00+01:00,21.812885284423828,21.991924285888672,21.733312606811523,21.981977462768555,21.370893093551224,893571,0.0,0.0,True
|
||||
2022-02-10 00:00:00+01:00,22.021764755249023,22.210750579833984,21.962085723876953,22.041658401489258,21.428912038708134,851844,0.0,0.0,True
|
||||
2022-02-11 00:00:00+01:00,21.882511138916016,22.06155014038086,21.713420867919922,21.882511138916016,21.274188949499745,893486,0.0,0.0,True
|
||||
2022-02-14 00:00:00+01:00,21.514488220214844,21.514488220214844,20.818225860595703,21.14646339416504,20.558603716304646,1234728,0.0,0.0,True
|
||||
2022-02-15 00:00:00+01:00,21.007211685180664,21.713420867919922,20.967424392700195,21.673633575439453,21.071116202770604,687285,0.0,0.0,True
|
||||
2022-02-16 00:00:00+01:00,21.713420867919922,22.06155014038086,21.713420867919922,22.06155014038086,21.448250613980445,798177,0.0,0.0,True
|
||||
2022-02-17 00:00:00+01:00,22.021764755249023,22.081443786621094,21.763153076171875,21.832778930664062,21.22583929197899,684218,0.0,0.0,True
|
||||
2022-02-18 00:00:00+01:00,21.832778930664062,21.892459869384766,21.385181427001953,21.544328689575195,20.945407415150648,737030,0.0,0.0,True
|
||||
2022-02-21 00:00:00+01:00,21.673633575439453,21.68358039855957,20.92763900756836,21.126571655273438,20.539265141032338,677844,0.0,0.0,True
|
||||
2022-02-22 00:00:00+01:00,20.529775619506836,21.196197509765625,20.32089614868164,20.95747947692871,20.374872764187796,1273455,0.0,0.0,True
|
||||
2022-02-23 00:00:00+01:00,21.415021896362305,21.862619400024414,20.987319946289062,21.216089248657227,20.626295168437693,1732461,0.0,0.0,True
|
||||
2022-02-24 00:00:00+01:00,20.48004150390625,20.877906799316406,19.51124382019043,19.70221710205078,19.154507899163683,2560976,0.0,0.0,True
|
||||
2022-02-25 00:00:00+01:00,19.903139114379883,20.291057586669922,19.475435256958008,20.201536178588867,19.639945736380405,1423396,0.0,0.0,True
|
||||
2022-02-28 00:00:00+01:00,19.773834228515625,19.903139114379883,19.308332443237305,19.837491989135742,19.28602115677132,1569727,0.0,0.0,True
|
||||
2022-03-01 00:00:00+01:00,19.77781105041504,19.95287322998047,18.73938751220703,18.73938751220703,18.218442947956373,1308216,0.0,0.0,True
|
||||
2022-03-02 00:00:00+01:00,18.536476135253906,19.12929344177246,18.17840003967285,18.966169357299805,18.438921056298593,1739856,0.0,0.0,True
|
||||
2022-03-03 00:00:00+01:00,19.001977920532227,19.077571868896484,18.297758102416992,18.361417770385742,17.85097943405268,834767,0.0,0.0,True
|
||||
2022-03-04 00:00:00+01:00,18.13463592529297,18.14259147644043,16.893299102783203,17.05642318725586,16.58226330183782,2249030,0.0,0.0,True
|
||||
2022-03-07 00:00:00+01:00,16.384033203125,17.10814666748047,15.516690254211426,16.380054473876953,15.924698623469626,2250820,0.0,0.0,True
|
||||
2022-03-08 00:00:00+01:00,16.21295166015625,16.941043853759766,16.16520881652832,16.805768966674805,16.338578581234838,1388112,0.0,0.0,True
|
||||
2022-03-09 00:00:00+01:00,17.207611083984375,18.22614288330078,17.17976188659668,18.22614288330078,17.719466176445042,1580329,0.0,0.0,True
|
||||
2022-03-10 00:00:00+01:00,18.38926887512207,18.429054260253906,17.44632911682129,17.696983337402344,17.205017256979872,1037018,0.0,0.0,True
|
||||
2022-03-11 00:00:00+01:00,17.88397979736328,18.369373321533203,17.585582733154297,17.943660736083984,17.44483715993438,985960,0.0,0.0,True
|
||||
2022-03-14 00:00:00+01:00,18.285823822021484,18.747344970703125,18.250015258789062,18.52056312561035,18.005702523261068,963701,0.0,0.0,True
|
||||
2022-03-15 00:00:00+01:00,19.79372787475586,19.893192291259766,17.99538230895996,18.15452766418457,17.649843120322757,2685295,0.0,0.0,True
|
||||
2022-03-16 00:00:00+01:00,18.78713035583496,18.9741268157959,18.369373321533203,18.76723861694336,18.245520816545586,1321768,0.0,0.0,True
|
||||
2022-03-17 00:00:00+01:00,18.89853286743164,18.966169357299805,18.433032989501953,18.854768753051758,18.330616020621715,1124314,0.0,0.0,True
|
||||
2022-03-18 00:00:00+01:00,18.894554138183594,18.98606300354004,18.47281837463379,18.7990665435791,18.276461893113282,1809744,0.0,0.0,True
|
||||
2022-03-21 00:00:00+01:00,18.7990665435791,19.15714454650879,18.763259887695312,18.91046905517578,18.384768538460154,703039,0.0,0.0,True
|
||||
2022-03-22 00:00:00+01:00,18.966169357299805,19.184995651245117,18.85079002380371,19.05767822265625,18.527885907033173,715772,0.0,0.0,True
|
||||
2022-03-23 00:00:00+01:00,19.121337890625,19.15714454650879,18.671751022338867,18.671751022338867,18.152686319152558,1351532,0.0,0.0,True
|
||||
2022-03-24 00:00:00+01:00,18.659814834594727,18.731430053710938,18.234100341796875,18.30173683166504,17.792958879225786,1286093,0.0,0.0,True
|
||||
2022-03-25 00:00:00+01:00,18.405181884765625,18.47281837463379,18.170442581176758,18.285823822021484,17.777488340941936,726494,0.0,0.0,True
|
||||
2022-03-28 00:00:00+02:00,18.393245697021484,18.759281158447266,18.329587936401367,18.433032989501953,17.92060409984496,837768,0.0,0.0,True
|
||||
2022-03-29 00:00:00+02:00,18.72745132446289,19.256610870361328,18.687665939331055,19.16908073425293,18.636190942710048,917861,0.0,0.0,True
|
||||
2022-03-30 00:00:00+02:00,19.15714454650879,19.15714454650879,18.46088218688965,18.50862693786621,17.994096802625698,823527,0.0,0.0,True
|
||||
2022-03-31 00:00:00+02:00,18.50862693786621,18.822938919067383,17.768600463867188,17.796449661254883,17.30171818169137,1780930,0.0,0.0,True
|
||||
2022-04-01 00:00:00+02:00,17.895915985107422,18.102806091308594,17.880001068115234,17.880001068115234,17.382948568119016,751206,0.0,0.0,True
|
||||
2022-04-04 00:00:00+02:00,17.92376708984375,17.991403579711914,17.517946243286133,17.79247283935547,17.2978517543729,836607,0.0,0.0,True
|
||||
2022-04-05 00:00:00+02:00,17.77655792236328,17.975488662719727,17.382671356201172,17.617412567138672,17.127658126880668,842142,0.0,0.0,True
|
||||
2022-04-06 00:00:00+02:00,17.577625274658203,17.625368118286133,16.87340545654297,17.016637802124023,16.543584541623215,1380130,0.0,0.0,True
|
||||
2022-04-07 00:00:00+02:00,17.10814666748047,17.382671356201172,16.865449905395508,16.89727783203125,16.427541822299425,857449,0.0,0.0,True
|
||||
2022-04-08 00:00:00+02:00,17.191696166992188,17.382671356201172,16.99674415588379,17.191696166992188,16.71377816911545,913588,0.0,0.0,True
|
||||
2022-04-11 00:00:00+02:00,17.219547271728516,17.549774169921875,17.036529541015625,17.203632354736328,16.72538228008083,1067867,0.0,0.0,True
|
||||
2022-04-12 00:00:00+02:00,17.00868034362793,17.565689086914062,16.833620071411133,17.565689086914062,17.077372036360696,1285128,0.0,0.0,True
|
||||
2022-04-13 00:00:00+02:00,17.438373565673828,17.525903701782227,17.267290115356445,17.506010055541992,17.019351481533796,697328,0.0,0.0,True
|
||||
2022-04-14 00:00:00+02:00,17.58160400390625,17.657197952270508,17.406543731689453,17.513967514038086,17.02708916518071,587256,0.0,0.0,True
|
||||
2022-04-19 00:00:00+02:00,17.54181671142578,17.69300651550293,17.418479919433594,17.517946243286133,17.030957202169166,962344,0.0,0.0,True
|
||||
2022-04-20 00:00:00+02:00,17.633325576782227,17.967531204223633,17.609453201293945,17.768600463867188,17.274643532442145,675733,0.0,0.0,True
|
||||
2022-04-21 00:00:00+02:00,17.860109329223633,18.38926887512207,17.860109329223633,18.28980255126953,17.781356377930393,946132,0.0,0.0,True
|
||||
2022-04-22 00:00:00+02:00,18.063018798828125,18.25399398803711,17.87204360961914,18.031190872192383,17.5299339736805,876938,0.0,0.0,True
|
||||
2022-04-25 00:00:00+02:00,17.71687889099121,17.891937255859375,17.549774169921875,17.629348754882812,17.139262237846047,857539,0.0,0.0,True
|
||||
2022-04-26 00:00:00+02:00,17.868066787719727,17.868066787719727,17.342885971069336,17.342885971069336,16.860763574676927,920938,0.0,0.0,True
|
||||
2022-04-27 00:00:00+02:00,17.42245864868164,17.513967514038086,16.865449905395508,17.430416107177734,16.945860388423046,995898,0.0,0.0,True
|
||||
2022-04-28 00:00:00+02:00,17.633325576782227,17.99538230895996,17.601497650146484,17.736770629882812,17.24369923653446,1172803,0.0,0.0,True
|
||||
2022-04-29 00:00:00+02:00,17.848173141479492,18.10678482055664,17.804407119750977,18.015274047851562,17.514460216056666,988594,0.0,0.0,True
|
||||
2022-05-02 00:00:00+02:00,17.88397979736328,18.05506134033203,16.90921401977539,17.74074935913086,17.24756566385293,1031151,0.0,0.0,True
|
||||
2022-05-03 00:00:00+02:00,17.848173141479492,17.93570327758789,17.506010055541992,17.808385848999023,17.31332229265675,1121197,0.0,0.0,True
|
||||
2022-05-04 00:00:00+02:00,18.747344970703125,19.10542106628418,18.532499313354492,18.846811294555664,18.322881556314783,2131889,0.0,0.0,True
|
||||
2022-05-05 00:00:00+02:00,19.18101692199707,19.37994956970215,18.138612747192383,18.17840003967285,17.673048122913535,1420586,0.0,0.0,True
|
||||
2022-05-06 00:00:00+02:00,18.110763549804688,18.560348510742188,17.97150993347168,18.369373321533203,17.858713898359614,967240,0.0,0.0,True
|
||||
2022-05-09 00:00:00+02:00,18.190336227416992,18.305715560913086,17.844194412231445,17.951616287231445,17.452570014571318,1063615,0.0,0.0,True
|
||||
2022-05-10 00:00:00+02:00,18.063018798828125,18.85079002380371,18.04710578918457,18.341524124145508,17.83164085878037,1106715,0.0,0.0,True
|
||||
2022-05-11 00:00:00+02:00,18.46088218688965,18.659814834594727,18.27786636352539,18.47281837463379,17.95928446972956,916544,0.0,0.0,True
|
||||
2022-05-12 00:00:00+02:00,18.04312515258789,18.261951446533203,17.784513473510742,18.222164154052734,17.71559974912657,899448,0.0,0.0,True
|
||||
2022-05-13 00:00:00+02:00,18.405181884765625,18.55636978149414,18.194313049316406,18.38528823852539,17.87418765598344,614260,0.0,0.0,True
|
||||
2022-05-16 00:00:00+02:00,18.381309509277344,18.612070083618164,18.24205780029297,18.417118072509766,17.90513356156111,734648,0.0,0.0,True
|
||||
2022-05-17 00:00:00+02:00,18.21420669555664,18.747344970703125,18.21420669555664,18.512605667114258,18.020961169004284,625555,0.0235,0.0,True
|
||||
2022-05-18 00:00:00+02:00,18.54443359375,18.592178344726562,18.357437133789062,18.357437133789062,17.869913837170763,676447,0.0,0.0,True
|
||||
2022-05-19 00:00:00+02:00,17.677091598510742,17.903873443603516,17.474180221557617,17.513967514038086,17.048843460304507,1239650,0.0,0.0,True
|
||||
2022-05-20 00:00:00+02:00,17.856130599975586,18.063018798828125,17.60547637939453,17.60547637939453,17.13792236757609,792884,0.0,0.0,True
|
||||
2022-05-23 00:00:00+02:00,17.85215187072754,17.987424850463867,17.633325576782227,17.987424850463867,17.509727290657995,661658,0.0,0.0,True
|
||||
2022-05-24 00:00:00+02:00,17.79247283935547,17.83623695373535,17.414501190185547,17.418479919433594,16.95589082346159,729103,0.0,0.0,True
|
||||
2022-05-25 00:00:00+02:00,17.617412567138672,17.89989471435547,17.394607543945312,17.8402156829834,17.36642741796716,645185,0.0,0.0,True
|
||||
2022-05-26 00:00:00+02:00,17.79247283935547,18.05506134033203,17.720855712890625,18.03516960144043,17.556203609079454,523872,0.0,0.0,True
|
||||
2022-05-27 00:00:00+02:00,18.031190872192383,18.198293685913086,17.94763946533203,18.198293685913086,17.71499558791078,578243,0.0,0.0,True
|
||||
2022-05-30 00:00:00+02:00,18.27786636352539,18.433032989501953,18.10678482055664,18.218185424804688,17.734358611477727,568621,0.0,0.0,True
|
||||
2022-05-31 00:00:00+02:00,18.1823787689209,18.218185424804688,17.97150993347168,18.122699737548828,17.64141019285213,1795488,0.0,0.0,True
|
||||
2022-06-01 00:00:00+02:00,18.293779373168945,18.44496726989746,18.17840003967285,18.28980255126953,17.804074495182356,494450,0.0,0.0,True
|
||||
2022-06-02 00:00:00+02:00,18.3494815826416,18.532499313354492,18.3494815826416,18.4569034576416,17.966737391440144,412331,0.0,0.0,True
|
||||
2022-06-03 00:00:00+02:00,18.592178344726562,18.639921188354492,18.433032989501953,18.564327239990234,18.071308404852203,487960,0.0,0.0,True
|
||||
2022-06-06 00:00:00+02:00,18.72745132446289,18.830896377563477,18.56830596923828,18.592178344726562,18.098420293634273,605186,0.0,0.0,True
|
||||
2022-06-07 00:00:00+02:00,18.500669479370117,18.540456771850586,18.32560920715332,18.468839645385742,17.978355768009287,606368,0.0,0.0,True
|
||||
2022-06-08 00:00:00+02:00,18.512605667114258,18.616050720214844,18.44496726989746,18.564327239990234,18.071308404852203,631100,0.0,0.0,True
|
||||
2022-06-09 00:00:00+02:00,18.452926635742188,18.82691764831543,18.401203155517578,18.41313934326172,17.924136208662464,1105870,0.0,0.0,True
|
||||
2022-06-10 00:00:00+02:00,18.273887634277344,18.31367301940918,17.685047149658203,17.685047149658203,17.215380086133635,933108,0.0,0.0,True
|
||||
2022-06-13 00:00:00+02:00,17.506010055541992,17.768600463867188,17.223526000976562,17.521923065185547,17.056586701229875,1102884,0.0,0.0,True
|
||||
2022-06-14 00:00:00+02:00,17.71289825439453,17.756664276123047,17.255355834960938,17.255355834960938,16.79709884463027,815872,0.0,0.0,True
|
||||
2022-06-15 00:00:00+02:00,17.486116409301758,18.015274047851562,17.42245864868164,17.621389389038086,17.153413067644134,987976,0.0,0.0,True
|
||||
2022-06-16 00:00:00+02:00,17.533859252929688,17.577625274658203,16.328332901000977,16.328332901000977,15.894697019635123,1421657,0.0,0.0,True
|
||||
2022-06-17 00:00:00+02:00,16.391990661621094,16.694366455078125,16.06574249267578,16.248760223388672,15.81723648893269,3094063,0.0,0.0,True
|
||||
2022-06-20 00:00:00+02:00,16.40790557861328,16.427799224853516,16.12542152404785,16.356182098388672,15.921804690199872,496948,0.0,0.0,True
|
||||
2022-06-21 00:00:00+02:00,16.491456985473633,16.821683883666992,16.427799224853516,16.48349952697754,16.045742945396203,563534,0.0,0.0,True
|
||||
2022-06-22 00:00:00+02:00,16.208974838256836,16.208974838256836,15.759387016296387,15.819067001342773,15.398955247429319,1050007,0.0,0.0,True
|
||||
2022-06-23 00:00:00+02:00,15.735515594482422,15.799174308776855,15.285928726196289,15.30980110168457,14.90321206915108,1064414,0.0,0.0,True
|
||||
2022-06-24 00:00:00+02:00,15.413246154785156,15.898639678955078,15.234207153320312,15.86681079864502,15.44543156585078,1215616,0.0,0.0,True
|
||||
2022-06-27 00:00:00+02:00,16.01799964904785,16.328332901000977,15.958318710327148,16.117464065551758,15.689428722382338,1182615,0.0,0.0,True
|
||||
2022-06-28 00:00:00+02:00,16.248760223388672,16.519306182861328,16.045848846435547,16.181123733520508,15.751397146944283,1274280,0.0,0.0,True
|
||||
2022-06-29 00:00:00+02:00,16.014020919799805,16.06574249267578,15.468947410583496,15.528626441955566,15.116227825546547,1058236,0.0,0.0,True
|
||||
2022-06-30 00:00:00+02:00,15.234207153320312,15.381417274475098,14.800535202026367,15.381417274475098,14.972926546783269,1934410,0.0,0.0,True
|
||||
2022-07-01 00:00:00+02:00,15.277972221374512,15.679815292358398,15.230228424072266,15.377437591552734,14.969054223284367,909034,0.0,0.0,True
|
||||
2022-07-04 00:00:00+02:00,15.564434051513672,15.791215896606445,15.488840103149414,15.687771797180176,15.271146074806529,798569,0.0,0.0,True
|
||||
2022-07-05 00:00:00+02:00,15.763365745544434,15.91455364227295,14.884086608886719,14.884086608886719,14.488804557219051,1966763,0.0,0.0,True
|
||||
2022-07-06 00:00:00+02:00,15.079039573669434,15.202378273010254,14.907958984375,15.110869407653809,14.709566366684761,938909,0.0,0.0,True
|
||||
2022-07-07 00:00:00+02:00,15.301843643188477,15.898639678955078,15.23818588256836,15.807130813598633,15.387335464787737,1170179,0.0,0.0,True
|
||||
2022-07-08 00:00:00+02:00,15.69572925567627,16.39596939086914,15.532605171203613,16.049827575683594,15.623586568249053,1372047,0.0,0.0,True
|
||||
2022-07-11 00:00:00+02:00,15.608199119567871,15.69572925567627,15.285928726196289,15.488840103149414,15.077497560195331,877119,0.0,0.0,True
|
||||
2022-07-12 00:00:00+02:00,15.381417274475098,15.556476593017578,14.983552932739258,15.520668983459473,15.108481772476305,1161955,0.0,0.0,True
|
||||
2022-07-13 00:00:00+02:00,15.425182342529297,15.647985458374023,15.234207153320312,15.357544898986816,14.94968838757254,1081802,0.0,0.0,True
|
||||
2022-07-14 00:00:00+02:00,15.333672523498535,15.357544898986816,14.728919982910156,14.888065338134766,14.492678286790394,896311,0.0,0.0,True
|
||||
2022-07-15 00:00:00+02:00,14.959680557250977,15.548519134521484,14.923872947692871,15.433138847351074,15.023276594776068,1160019,0.0,0.0,True
|
||||
2022-07-18 00:00:00+02:00,15.970254898071289,16.316396713256836,15.894660949707031,16.133378982543945,15.704919422450384,1770123,0.0,0.0,True
|
||||
2022-07-19 00:00:00+02:00,16.010042190551758,16.698345184326172,15.755409240722656,16.48349952697754,16.045742945396203,1574206,0.0,0.0,True
|
||||
2022-07-20 00:00:00+02:00,16.551136016845703,16.67845344543457,16.145315170288086,16.439735412597656,16.003140356546087,876721,0.0,0.0,True
|
||||
2022-07-21 00:00:00+02:00,16.30048179626465,16.646623611450195,16.16520881652832,16.364139556884766,15.929552149342557,1014598,0.0,0.0,True
|
||||
2022-07-22 00:00:00+02:00,16.244781494140625,16.463605880737305,15.98219108581543,16.037891387939453,15.611968191679907,1100753,0.0,0.0,True
|
||||
2022-07-25 00:00:00+02:00,16.014020919799805,16.39596939086914,15.874768257141113,16.11348533630371,15.685553586738559,826151,0.0,0.0,True
|
||||
2022-07-26 00:00:00+02:00,16.11348533630371,16.133378982543945,15.600241661071777,15.715621948242188,15.298257963588599,1071673,0.0,0.0,True
|
||||
2022-07-27 00:00:00+02:00,15.894660949707031,15.970254898071289,15.703685760498047,15.950362205505371,15.526763013979673,1076946,0.0,0.0,True
|
||||
2022-07-28 00:00:00+02:00,16.368118286132812,16.686410903930664,16.232845306396484,16.551136016845703,16.11158369345705,1713701,0.0,0.0,True
|
||||
2022-07-29 00:00:00+02:00,16.634687423706055,17.084274291992188,16.551136016845703,17.00868034362793,16.55697541767005,1096515,0.0,0.0,True
|
||||
2022-08-01 00:00:00+02:00,17.088253021240234,17.303098678588867,16.83759880065918,16.861469268798828,16.413675544979213,698449,0.0,0.0,True
|
||||
2022-08-02 00:00:00+02:00,16.833620071411133,16.992765426635742,16.674474716186523,16.937063217163086,16.48725953396542,683927,0.0,0.0,True
|
||||
2022-08-03 00:00:00+02:00,16.92115020751953,17.175783157348633,16.83759880065918,17.12008285522461,16.66542016065345,520776,0.0,0.0,True
|
||||
2022-08-04 00:00:00+02:00,17.132017135620117,17.334928512573242,17.004701614379883,17.064380645751953,16.61119638308931,770841,0.0,0.0,True
|
||||
2022-08-05 00:00:00+02:00,17.100189208984375,17.283206939697266,16.821683883666992,17.104167938232422,16.649926648440527,676884,0.0,0.0,True
|
||||
2022-08-08 00:00:00+02:00,17.283206939697266,17.47020149230957,17.076316833496094,17.319013595581055,16.859067269192213,640299,0.0,0.0,True
|
||||
2022-08-09 00:00:00+02:00,17.247398376464844,17.342885971069336,16.9808292388916,17.112125396728516,16.657674107583208,513653,0.0,0.0,True
|
||||
2022-08-10 00:00:00+02:00,17.084274291992188,17.43439483642578,16.90921401977539,17.394607543945312,16.932651258178424,565334,0.0,0.0,True
|
||||
2022-08-11 00:00:00+02:00,17.45826530456543,17.474180221557617,17.15191078186035,17.267290115356445,16.808717221199412,740132,0.0,0.0,True
|
||||
2022-08-12 00:00:00+02:00,17.23944091796875,17.486116409301758,17.231483459472656,17.342885971069336,16.88230542840294,966868,0.0,0.0,True
|
||||
2022-08-15 00:00:00+02:00,17.346864700317383,17.474180221557617,17.064380645751953,17.243419647216797,16.785480468061124,404314,0.0,0.0,True
|
||||
2022-08-16 00:00:00+02:00,17.342885971069336,17.426437377929688,17.175783157348633,17.36277961730957,16.90166985804233,615567,0.0,0.0,True
|
||||
2022-08-17 00:00:00+02:00,17.44632911682129,17.525903701782227,16.742111206054688,16.76598358154297,16.320724314208736,1020374,0.0,0.0,True
|
||||
2022-08-18 00:00:00+02:00,16.821683883666992,17.25137710571289,16.769962310791016,16.853513717651367,16.40592949190897,738694,0.0,0.0,True
|
||||
2022-08-19 00:00:00+02:00,16.69038963317871,16.901256561279297,16.606836318969727,16.606836318969727,16.165803252803872,628184,0.0,0.0,True
|
||||
2022-08-22 00:00:00+02:00,16.479520797729492,16.527265548706055,15.92251205444336,15.978212356567383,15.553874902761745,866276,0.0,0.0,True
|
||||
2022-08-23 00:00:00+02:00,15.942404747009277,16.292524337768555,15.918533325195312,16.292524337768555,15.859837671710368,860233,0.0,0.0,True
|
||||
2022-08-24 00:00:00+02:00,16.268653869628906,16.308439254760742,15.950362205505371,16.240802764892578,15.809489029790006,704240,0.0,0.0,True
|
||||
2022-08-25 00:00:00+02:00,16.388011932373047,16.523286819458008,16.216930389404297,16.292524337768555,15.859837671710368,479490,0.0,0.0,True
|
||||
2022-08-26 00:00:00+02:00,16.439735412597656,16.598880767822266,15.958318710327148,15.990147590637207,15.56549046718601,546820,0.0,0.0,True
|
||||
2022-08-29 00:00:00+02:00,15.91455364227295,16.44769287109375,15.743473052978516,16.43177604675293,15.995390085258524,771344,0.0,0.0,True
|
||||
2022-08-30 00:00:00+02:00,16.54317855834961,16.67845344543457,16.15327262878418,16.248760223388672,15.81723648893269,741509,0.0,0.0,True
|
||||
2022-08-31 00:00:00+02:00,16.356182098388672,16.44371223449707,16.0418701171875,16.0418701171875,15.615841921251251,956161,0.0,0.0,True
|
||||
2022-09-01 00:00:00+02:00,15.978212356567383,15.978212356567383,15.691749572753906,15.755409240722656,15.336988228939816,998562,0.0,0.0,True
|
||||
2022-09-02 00:00:00+02:00,16.161230087280273,16.519306182861328,15.962298393249512,16.391990661621094,15.956664038124627,997552,0.0,0.0,True
|
||||
2022-09-05 00:00:00+02:00,15.874768257141113,15.91455364227295,15.520668983459473,15.723580360412598,15.306005422731282,1129909,0.0,0.0,True
|
||||
2022-09-06 00:00:00+02:00,15.763365745544434,16.09359359741211,15.683793067932129,15.86681079864502,15.44543156585078,638791,0.0,0.0,True
|
||||
2022-09-07 00:00:00+02:00,15.616155624389648,16.264673233032227,15.58034896850586,16.21295166015625,15.782378547080377,819365,0.0,0.0,True
|
||||
2022-09-08 00:00:00+02:00,16.292524337768555,16.364139556884766,15.954340934753418,16.14133644104004,15.712665475520629,690130,0.0,0.0,True
|
||||
2022-09-09 00:00:00+02:00,16.19305992126465,16.575008392333984,16.19305992126465,16.427799224853516,15.991520573904502,623223,0.0,0.0,True
|
||||
2022-09-12 00:00:00+02:00,16.614795684814453,17.076316833496094,16.571029663085938,16.98480796813965,16.533737258459322,880959,0.0,0.0,True
|
||||
2022-09-13 00:00:00+02:00,17.02061653137207,17.549774169921875,16.698345184326172,16.722217559814453,16.278118913213735,1949078,0.0,0.0,True
|
||||
2022-09-14 00:00:00+02:00,16.55511474609375,16.65458106994629,16.06574249267578,16.316396713256836,15.883077236993536,1147799,0.0,0.0,True
|
||||
2022-09-15 00:00:00+02:00,16.316396713256836,16.50737190246582,16.01799964904785,16.12542152404785,15.697173369380144,704698,0.0,0.0,True
|
||||
2022-09-16 00:00:00+02:00,15.92648983001709,16.05380630493164,15.647985458374023,15.954340934753418,15.530635337478573,1934284,0.0,0.0,True
|
||||
2022-09-19 00:00:00+02:00,15.890682220458984,16.419841766357422,15.791215896606445,16.368118286132812,15.933425878913898,961766,0.0,0.0,True
|
||||
2022-09-20 00:00:00+02:00,16.44769287109375,16.55511474609375,15.930468559265137,15.99412727355957,15.569367008902228,712846,0.0,0.0,True
|
||||
2022-09-21 00:00:00+02:00,15.894660949707031,16.137357711791992,15.815088272094727,16.1294002532959,15.701045692879042,557165,0.0,0.0,True
|
||||
2022-09-22 00:00:00+02:00,15.727558135986328,16.197038650512695,15.667879104614258,16.069721221923828,15.64295240396088,892616,0.0,0.0,True
|
||||
2022-09-23 00:00:00+02:00,16.0418701171875,16.161230087280273,15.64002799987793,15.854874610900879,15.433811783209194,1425407,0.0,0.0,True
|
||||
2022-09-26 00:00:00+02:00,15.675835609436035,16.037891387939453,15.604220390319824,15.604220390319824,15.189814626677634,823367,0.0,0.0,True
|
||||
2022-09-27 00:00:00+02:00,15.6360502243042,15.886704444885254,15.492818832397461,15.687771797180176,15.271146074806529,1239006,0.0,0.0,True
|
||||
2022-09-28 00:00:00+02:00,15.433138847351074,16.109508514404297,15.170549392700195,15.990147590637207,15.56549046718601,1753368,0.0,0.0,True
|
||||
2022-09-29 00:00:00+02:00,15.986169815063477,15.986169815063477,15.40926742553711,15.516690254211426,15.104608042904962,1373640,0.0,0.0,True
|
||||
2022-09-30 00:00:00+02:00,15.6360502243042,15.894660949707031,15.528626441955566,15.842939376831055,15.42219340664005,1225082,0.0,0.0,True
|
||||
2022-10-03 00:00:00+02:00,15.671856880187988,16.419841766357422,15.628091812133789,16.34822654724121,15.91406144927451,968647,0.0,0.0,True
|
||||
2022-10-04 00:00:00+02:00,16.618772506713867,17.267290115356445,16.618772506713867,17.267290115356445,16.808717221199412,1425231,0.0,0.0,True
|
||||
2022-10-05 00:00:00+02:00,17.100189208984375,17.35084342956543,17.016637802124023,17.08029556274414,16.626688489229796,1216119,0.0,0.0,True
|
||||
2022-10-06 00:00:00+02:00,17.203632354736328,17.32697105407715,16.88534164428711,16.976850509643555,16.525989799316637,825166,0.0,0.0,True
|
||||
2022-10-07 00:00:00+02:00,16.976850509643555,17.12803840637207,16.65458106994629,16.730175018310547,16.28586637235642,839674,0.0,0.0,True
|
||||
2022-10-10 00:00:00+02:00,16.610815048217773,17.56966781616211,16.586944580078125,17.402565002441406,16.940398717321106,1029281,0.0,0.0,True
|
||||
2022-10-11 00:00:00+02:00,17.088253021240234,17.23944091796875,16.284568786621094,16.463605880737305,16.026375703611937,2020228,0.0,0.0,True
|
||||
2022-10-12 00:00:00+02:00,16.499414443969727,16.929107666015625,16.320375442504883,16.789854049682617,16.343959661274585,1510536,0.0,0.0,True
|
||||
2022-10-13 00:00:00+02:00,16.694366455078125,17.17976188659668,16.384033203125,17.17976188659668,16.72351485564406,1551570,0.0,0.0,True
|
||||
2022-10-14 00:00:00+02:00,17.525903701782227,17.69300651550293,16.841577529907227,17.012659072875977,16.560847741168953,1388605,0.0,0.0,True
|
||||
2022-10-17 00:00:00+02:00,17.012659072875977,17.49407386779785,16.913192749023438,17.287185668945312,16.82808305691124,857670,0.0,0.0,True
|
||||
2022-10-18 00:00:00+02:00,17.43439483642578,17.951616287231445,17.39858627319336,17.617412567138672,17.14954215021767,1118895,0.0,0.0,True
|
||||
2022-10-19 00:00:00+02:00,17.732791900634766,17.820322036743164,17.565689086914062,17.58160400390625,17.114684208365354,659672,0.0,0.0,True
|
||||
2022-10-20 00:00:00+02:00,17.4980525970459,17.796449661254883,17.414501190185547,17.677091598510742,17.20763543913583,869126,0.0,0.0,True
|
||||
2022-10-21 00:00:00+02:00,17.506010055541992,17.85215187072754,17.346864700317383,17.85215187072754,17.378044388463863,781749,0.0,0.0,True
|
||||
2022-10-24 00:00:00+02:00,18.699600219726562,18.834875106811523,17.708919525146484,18.345502853393555,17.858295460601617,1695268,0.0,0.0,True
|
||||
2022-10-25 00:00:00+02:00,18.440990447998047,18.627986907958984,17.931724548339844,18.202272415161133,17.71886931748212,1131150,0.0,0.0,True
|
||||
2022-10-26 00:00:00+02:00,18.22614288330078,18.43701171875,17.975488662719727,18.329587936401367,17.84280194838869,1222905,0.0,0.0,True
|
||||
2022-10-27 00:00:00+02:00,18.341524124145508,18.600135803222656,18.08291244506836,18.293779373168945,17.80794681868126,778065,0.0,0.0,True
|
||||
2022-10-28 00:00:00+02:00,18.078933715820312,18.32560920715332,17.975488662719727,18.269908905029297,17.784708659470528,1099727,0.0,0.0,True
|
||||
2022-10-31 00:00:00+01:00,18.369373321533203,18.532499313354492,18.14259147644043,18.150548934936523,17.66851786341688,1018936,0.0,0.0,True
|
||||
2022-11-01 00:00:00+01:00,18.293779373168945,18.492712020874023,18.063018798828125,18.15452766418457,17.672391592988223,1016061,0.0,0.0,True
|
||||
2022-11-02 00:00:00+01:00,18.186357498168945,18.194313049316406,17.88397979736328,18.063018798828125,17.583315497861527,1299861,0.0,0.0,True
|
||||
2022-11-03 00:00:00+01:00,17.69300651550293,18.015274047851562,17.406543731689453,17.98344612121582,17.505852155014214,1179101,0.0,0.0,True
|
||||
2022-11-04 00:00:00+01:00,18.202272415161133,18.894554138183594,18.15452766418457,18.791109085083008,18.292067402173036,1369272,0.0,0.0,True
|
||||
2022-11-07 00:00:00+01:00,18.759281158447266,19.391883850097656,18.659814834594727,19.336183547973633,18.82266711623115,1259541,0.0,0.0,True
|
||||
2022-11-08 00:00:00+01:00,19.332204818725586,19.566944122314453,19.188974380493164,19.41177749633789,18.896252511289795,886906,0.0,0.0,True
|
||||
2022-11-09 00:00:00+01:00,19.415756225585938,19.415756225585938,18.954233169555664,19.208866119384766,18.69873026710726,1198007,0.0,0.0,True
|
||||
2022-11-10 00:00:00+01:00,19.153165817260742,19.59479522705078,19.03778648376465,19.586837768554688,19.066662866690272,1410472,0.0,0.0,True
|
||||
2022-11-11 00:00:00+01:00,19.59479522705078,19.857385635375977,19.562965393066406,19.78974723815918,19.264183704800367,1274687,0.0,0.0,True
|
||||
2022-11-14 00:00:00+01:00,19.81361961364746,20.112018585205078,19.690282821655273,20.032445907592773,19.50044043255144,1295287,0.0,0.0,True
|
||||
2022-11-15 00:00:00+01:00,20.01255226135254,20.191591262817383,19.61071014404297,19.805662155151367,19.279678623085733,1056914,0.0,0.0,True
|
||||
2022-11-16 00:00:00+01:00,19.75394058227539,19.785770416259766,19.276504516601562,19.44758415222168,18.931107640997233,1015000,0.0,0.0,True
|
||||
2022-11-17 00:00:00+01:00,19.4833927154541,19.65447425842285,19.09746551513672,19.296396255493164,18.783935444807494,644501,0.0,0.0,True
|
||||
2022-11-18 00:00:00+01:00,19.42371368408203,19.666410446166992,19.332204818725586,19.666410446166992,19.1441233973927,829590,0.0,0.0,True
|
||||
2022-11-21 00:00:00+01:00,19.598773956298828,19.606731414794922,19.02187156677246,19.101444244384766,18.59416065976764,918183,0.0,0.0,True
|
||||
2022-11-22 00:00:00+01:00,19.137252807617188,19.49930763244629,19.073593139648438,19.395862579345703,18.880761811221753,915438,0.0,0.0,True
|
||||
2022-11-23 00:00:00+01:00,19.475435256958008,19.51124382019043,19.149187088012695,19.264568328857422,18.752952638598963,867427,0.0,0.0,True
|
||||
2022-11-24 00:00:00+01:00,19.31231117248535,19.551029205322266,19.31231117248535,19.539094924926758,19.02018795434125,658838,0.0,0.0,True
|
||||
2022-11-25 00:00:00+01:00,19.535114288330078,19.574901580810547,19.371990203857422,19.419734954833984,18.90399856436004,444192,0.0,0.0,True
|
||||
2022-11-28 00:00:00+01:00,19.296396255493164,19.356077194213867,19.085529327392578,19.16908073425293,18.660001407828485,743198,0.0,0.0,True
|
||||
2022-11-29 00:00:00+01:00,18.830896377563477,18.978105545043945,18.572284698486328,18.72745132446289,18.230101789755967,1801344,0.0,0.0,True
|
||||
2022-11-30 00:00:00+01:00,18.89853286743164,18.92638397216797,18.405181884765625,18.675729751586914,18.179751741763166,1555300,0.0,0.0,True
|
||||
2022-12-01 00:00:00+01:00,18.87466049194336,18.958213806152344,18.56830596923828,18.73938751220703,18.241720166325113,1102744,0.0,0.0,True
|
||||
2022-12-02 00:00:00+01:00,18.663793563842773,19.013914108276367,18.55636978149414,19.005956649780273,18.501209428997157,783142,0.0,0.0,True
|
||||
2022-12-05 00:00:00+01:00,18.966169357299805,19.061656951904297,18.73938751220703,18.86272621154785,18.36178328587766,726414,0.0,0.0,True
|
||||
2022-12-06 00:00:00+01:00,18.870683670043945,19.073593139648438,18.791109085083008,18.962190628051758,18.45860684014704,752418,0.0,0.0,True
|
||||
2022-12-07 00:00:00+01:00,18.922405242919922,18.958213806152344,18.572284698486328,18.62002944946289,18.125532182416347,1312303,0.0,0.0,True
|
||||
2022-12-08 00:00:00+01:00,18.48475456237793,18.759281158447266,18.421096801757812,18.516584396362305,18.024832086430745,1077991,0.0,0.0,True
|
||||
2022-12-09 00:00:00+01:00,18.56830596923828,18.890575408935547,18.52056312561035,18.83885383605957,18.338543720594494,876148,0.0,0.0,True
|
||||
2022-12-12 00:00:00+01:00,18.735408782958984,18.763259887695312,18.417118072509766,18.468839645385742,17.978355768009287,1151398,0.0,0.0,True
|
||||
2022-12-13 00:00:00+01:00,18.604114532470703,19.065635681152344,18.552391052246094,18.942298889160156,18.43924100443521,1226494,0.0,0.0,True
|
||||
2022-12-14 00:00:00+01:00,18.858747482299805,19.017892837524414,18.75530242919922,18.8865966796875,18.38502144508839,958418,0.0,0.0,True
|
||||
2022-12-15 00:00:00+01:00,18.73938751220703,18.751323699951172,18.369373321533203,18.47281837463379,17.982229497580626,1115743,0.0,0.0,True
|
||||
2022-12-16 00:00:00+01:00,18.4569034576416,18.627986907958984,18.329587936401367,18.564327239990234,18.071308404852203,1941860,0.0,0.0,True
|
||||
2022-12-19 00:00:00+01:00,18.58422088623047,18.75530242919922,18.548412322998047,18.627986907958984,18.133276829414147,778150,0.0,0.0,True
|
||||
2022-12-20 00:00:00+01:00,18.504648208618164,18.7990665435791,18.393245697021484,18.7990665435791,18.29981204917084,935164,0.0,0.0,True
|
||||
2022-12-21 00:00:00+01:00,18.89853286743164,19.244674682617188,18.8865966796875,19.208866119384766,18.69873026710726,1124419,0.0,0.0,True
|
||||
2022-12-22 00:00:00+01:00,19.272525787353516,19.38790512084961,18.783153533935547,18.82691764831543,18.32692253188047,1217165,0.0,0.0,True
|
||||
2022-12-23 00:00:00+01:00,18.89853286743164,19.14520835876465,18.81498146057129,19.0338077545166,18.52832131777923,552525,0.0,0.0,True
|
||||
2022-12-27 00:00:00+01:00,19.177038192749023,19.24069595336914,19.03778648376465,19.04972267150879,18.543813423919715,387951,0.0,0.0,True
|
||||
2022-12-28 00:00:00+01:00,19.09746551513672,19.177038192749023,18.934341430664062,19.005956649780273,18.501209428997157,517744,0.0,0.0,True
|
||||
2022-12-29 00:00:00+01:00,19.001977920532227,19.077571868896484,18.8865966796875,19.045743942260742,18.539939694348377,398794,0.0,0.0,True
|
||||
2022-12-30 00:00:00+01:00,18.946277618408203,19.017892837524414,18.75530242919922,18.791109085083008,18.292067402173036,449339,0.0,0.0,True
|
||||
2023-01-02 00:00:00+01:00,18.990041732788086,19.383926391601562,18.914447784423828,19.383926391601562,18.869143434652607,671340,0.0,0.0,True
|
||||
2023-01-03 00:00:00+01:00,19.356077194213867,19.78179168701172,19.344141006469727,19.435649871826172,18.919492076572965,983215,0.0,0.0,True
|
||||
2023-01-04 00:00:00+01:00,19.48737144470215,19.982711791992188,19.44758415222168,19.94292640686035,19.413296280956878,1333355,0.0,0.0,True
|
||||
2023-01-05 00:00:00+01:00,19.932979583740234,20.121965408325195,19.845449447631836,20.002605438232422,19.471390975947482,1261924,0.0,0.0,True
|
||||
2023-01-06 00:00:00+01:00,20.112018585205078,20.410415649414062,19.95287322998047,20.410415649414062,19.86837162606201,641716,0.0,0.0,True
|
||||
2023-01-09 00:00:00+01:00,20.410415649414062,20.569562911987305,20.32089614868164,20.440256118774414,19.897418270521097,839910,0.0,0.0,True
|
||||
2023-01-10 00:00:00+01:00,20.48004150390625,20.48004150390625,19.932979583740234,20.17169761657715,19.635990033954716,1099813,0.0,0.0,True
|
||||
2023-01-11 00:00:00+01:00,20.241323471069336,20.838119506835938,20.10207176208496,20.599401473999023,20.052337925853514,1479852,0.0,0.0,True
|
||||
2023-01-12 00:00:00+01:00,20.60934829711914,20.758546829223633,20.470096588134766,20.639188766479492,20.091066785132295,1067892,0.0,0.0,True
|
||||
2023-01-13 00:00:00+01:00,20.559614181518555,21.01715850830078,20.430309295654297,20.788387298583984,20.236304225645025,1563851,0.0,0.0,True
|
||||
2023-01-16 00:00:00+01:00,20.589454650878906,20.72870635986328,20.181644439697266,20.70881462097168,20.173789489152337,790612,0.0154,0.0,True
|
||||
2023-01-17 00:00:00+01:00,20.698867797851562,20.997264862060547,20.499935150146484,20.659080505371094,20.125339438911386,917298,0.0,0.0,True
|
||||
2023-01-18 00:00:00+01:00,20.649133682250977,20.80828094482422,20.39052391052246,20.688920974731445,20.154409208480754,976454,0.0,0.0,True
|
||||
2023-01-19 00:00:00+01:00,20.569562911987305,20.57950782775879,20.26121711730957,20.39052391052246,19.86372323867117,888012,0.0,0.0,True
|
||||
2023-01-20 00:00:00+01:00,20.529775619506836,20.649133682250977,20.340789794921875,20.619295120239258,20.08658148332024,757103,0.0,0.0,True
|
||||
2023-01-23 00:00:00+01:00,20.678974151611328,20.70881462097168,20.5098819732666,20.57950782775879,20.047822224853086,540245,0.0,0.0,True
|
||||
2023-01-24 00:00:00+01:00,20.688920974731445,20.72870635986328,20.599401473999023,20.72870635986328,20.19316455831987,497230,0.0,0.0,True
|
||||
2023-01-25 00:00:00+01:00,20.72870635986328,20.788387298583984,20.539722442626953,20.72870635986328,20.19316455831987,610198,0.0,0.0,True
|
||||
2023-01-26 00:00:00+01:00,20.82817268371582,21.01715850830078,20.549667358398438,21.01715850830078,20.47416625073572,1177819,0.0,0.0,True
|
||||
2023-01-27 00:00:00+01:00,21.0271053314209,21.315555572509766,20.937585830688477,21.196197509765625,20.648580959523894,1399061,0.0,0.0,True
|
||||
2023-01-30 00:00:00+01:00,21.106678009033203,21.196197509765625,20.967424392700195,21.096731185913086,20.551682161918006,1048142,0.0,0.0,True
|
||||
2023-01-31 00:00:00+01:00,21.156410217285156,21.255876541137695,21.007211685180664,21.216089248657227,20.667957331567443,1153987,0.0,0.0,True
|
||||
2023-02-01 00:00:00+01:00,21.36528968811035,21.633846282958984,21.295663833618164,21.604007720947266,21.045855215837157,1127903,0.0,0.0,True
|
||||
2023-02-02 00:00:00+01:00,21.604007720947266,21.922298431396484,21.514488220214844,21.792993545532227,21.2299568077711,1405008,0.0,0.0,True
|
||||
2023-02-03 00:00:00+01:00,21.733312606811523,21.981977462768555,21.6437931060791,21.981977462768555,21.414057096829026,1224408,0.0,0.0,True
|
||||
2023-02-06 00:00:00+01:00,21.713420867919922,21.862619400024414,21.514488220214844,21.6437931060791,21.08461056567628,1078283,0.0,0.0,True
|
||||
2023-02-07 00:00:00+01:00,21.812885284423828,21.912351608276367,21.6437931060791,21.65374183654785,21.0943039632021,983431,0.0,0.0,True
|
||||
2023-02-08 00:00:00+01:00,21.68358039855957,22.051603317260742,21.68358039855957,21.832778930664062,21.268716066238255,983919,0.0,0.0,True
|
||||
2023-02-09 00:00:00+01:00,21.862619400024414,22.03171157836914,21.74325942993164,21.892459869384766,21.326852999624965,921355,0.0,0.0,True
|
||||
2023-02-10 00:00:00+01:00,21.773099899291992,21.892459869384766,21.39512825012207,21.58411407470703,21.026474935165574,931770,0.0,0.0,True
|
||||
2023-02-13 00:00:00+01:00,21.613954544067383,21.68358039855957,21.484647750854492,21.534381866455078,20.978026187800634,653816,0.0,0.0,True
|
||||
2023-02-14 00:00:00+01:00,21.564220428466797,21.6437931060791,21.415021896362305,21.484647750854492,20.929576137559682,566610,0.0,0.0,True
|
||||
2023-02-15 00:00:00+01:00,21.385181427001953,21.72336769104004,21.345396041870117,21.703474044799805,21.142751407691026,971141,0.0,0.0,True
|
||||
2023-02-16 00:00:00+01:00,21.733312606811523,21.852672576904297,21.58411407470703,21.753206253051758,21.19119885217995,860626,0.0,0.0,True
|
||||
2023-02-17 00:00:00+01:00,21.604007720947266,21.822832107543945,21.484647750854492,21.763153076171875,21.200887038201728,558814,0.0,0.0,True
|
||||
2023-02-20 00:00:00+01:00,21.78304672241211,22.340055465698242,21.78304672241211,22.340055465698242,21.762886514405384,997833,0.0,0.0,True
|
||||
2023-02-21 00:00:00+01:00,22.300268173217773,22.4693603515625,22.111284255981445,22.19085693359375,21.61754157518657,907456,0.0,0.0,True
|
||||
2023-02-22 00:00:00+01:00,21.59406089782715,22.011817932128906,21.484647750854492,21.97203254699707,21.404370213683265,1114536,0.0,0.0,True
|
||||
2023-02-23 00:00:00+01:00,22.06155014038086,22.06155014038086,21.05694580078125,21.126571655273438,20.580754537239393,2085708,0.0,0.0,True
|
||||
2023-02-24 00:00:00+01:00,21.126571655273438,21.763153076171875,20.967424392700195,21.07683753967285,20.532304486998445,1493284,0.0,0.0,True
|
||||
2023-02-27 00:00:00+01:00,21.285715103149414,21.604007720947266,21.206144332885742,21.454809188842773,20.900508973742337,744495,0.0,0.0,True
|
||||
2023-02-28 00:00:00+01:00,21.325502395629883,21.72336769104004,21.265823364257812,21.534381866455078,20.978026187800634,1797489,0.0,0.0,True
|
||||
2023-03-01 00:00:00+01:00,21.613954544067383,21.663686752319336,21.30561065673828,21.37523651123047,20.82299175968404,1095414,0.0,0.0,True
|
||||
2023-03-02 00:00:00+01:00,21.295663833618164,21.43491554260254,21.096731185913086,21.355342864990234,20.803612781888468,729153,0.0,0.0,True
|
||||
2023-03-03 00:00:00+01:00,21.454809188842773,21.673633575439453,21.444862365722656,21.59406089782715,21.036164424063358,731340,0.0,0.0,True
|
||||
2023-03-06 00:00:00+01:00,21.59406089782715,21.633846282958984,21.136518478393555,21.136518478393555,20.59044272326117,1177638,0.0,0.0,True
|
||||
2023-03-07 00:00:00+01:00,21.14646339416504,21.255876541137695,21.0469970703125,21.126571655273438,20.580754537239393,894823,0.0,0.0,True
|
||||
2023-03-08 00:00:00+01:00,21.0271053314209,21.216089248657227,20.7386531829834,21.216089248657227,20.667957331567443,1145240,0.0,0.0,True
|
||||
2023-03-09 00:00:00+01:00,21.07683753967285,21.196197509765625,21.01715850830078,21.066890716552734,20.522613695224646,611676,0.0,0.0,True
|
||||
2023-03-10 00:00:00+01:00,20.76849365234375,21.007211685180664,20.589454650878906,20.897798538208008,20.357888475334253,1111284,0.0,0.0,True
|
||||
2023-03-13 00:00:00+01:00,20.688920974731445,20.778440475463867,20.07223129272461,20.221431732177734,19.698996715904766,1243550,0.0,0.0,True
|
||||
2023-03-14 00:00:00+01:00,20.181644439697266,20.470096588134766,19.903139114379883,20.400468826293945,19.873411424692947,1301756,0.0,0.0,True
|
||||
2023-03-15 00:00:00+01:00,20.430309295654297,20.440256118774414,19.093486785888672,19.121337890625,18.627325172748737,2538134,0.0,0.0,True
|
||||
2023-03-16 00:00:00+01:00,19.578880310058594,19.68232536315918,18.914447784423828,19.344141006469727,18.844372590386367,1772646,0.0,0.0,True
|
||||
2023-03-17 00:00:00+01:00,19.395862579345703,19.68232536315918,18.87466049194336,19.20488739013672,18.708717140065342,2459464,0.0,0.0,True
|
||||
2023-03-20 00:00:00+01:00,19.196931838989258,19.531137466430664,18.723472595214844,19.467479705810547,18.96452251329411,903163,0.0,0.0,True
|
||||
2023-03-21 00:00:00+01:00,19.73006820678711,20.17169761657715,19.646516799926758,19.972766876220703,19.456755584832088,1270092,0.0,0.0,True
|
||||
2023-03-22 00:00:00+01:00,19.932979583740234,20.340789794921875,19.869321823120117,20.032445907592773,19.514893821094812,1100120,0.0,0.0,True
|
||||
2023-03-23 00:00:00+01:00,19.962818145751953,19.962818145751953,19.6584529876709,19.845449447631836,19.332728302914013,1594495,0.0,0.0,True
|
||||
2023-03-24 00:00:00+01:00,19.74200439453125,19.761898040771484,19.165102005004883,19.726089477539062,19.216454436140587,2008460,0.0,0.0,True
|
||||
2023-03-27 00:00:00+02:00,20.07223129272461,20.301002502441406,19.833513259887695,20.221431732177734,19.698996715904766,1382281,0.0,0.0,True
|
||||
2023-03-28 00:00:00+02:00,20.42036247253418,20.559614181518555,20.13191032409668,20.470096588134766,19.941239149853455,1220512,0.0,0.0,True
|
||||
2023-03-29 00:00:00+02:00,20.559614181518555,20.639188766479492,20.370630264282227,20.539722442626953,20.009065572137956,791707,0.0,0.0,True
|
||||
2023-03-30 00:00:00+02:00,20.659080505371094,21.01715850830078,20.629241943359375,20.82817268371582,20.290060750173744,968974,0.0,0.0,True
|
||||
2023-03-31 00:00:00+02:00,20.82817268371582,21.01715850830078,20.748600006103516,20.95747947692871,20.416030620225015,1172265,0.0,0.0,True
|
||||
2023-04-03 00:00:00+02:00,20.967424392700195,21.066890716552734,20.688920974731445,20.937585830688477,20.39665033955343,1141103,0.0,0.0,True
|
||||
2023-04-04 00:00:00+02:00,21.08678436279297,21.186250686645508,20.858013153076172,20.858013153076172,20.31913182261912,728163,0.0,0.0,True
|
||||
2023-04-05 00:00:00+02:00,20.897798538208008,20.947532653808594,20.46014976501465,20.499935150146484,19.970305010794792,1310588,0.0,0.0,True
|
||||
2023-04-06 00:00:00+02:00,20.649133682250977,20.758546829223633,20.470096588134766,20.589454650878906,20.057513016626885,957116,0.0,0.0,True
|
||||
2023-04-11 00:00:00+02:00,20.887853622436523,21.216089248657227,20.867958068847656,21.196197509765625,20.648580959523894,1155390,0.0,0.0,True
|
||||
2023-04-12 00:00:00+02:00,21.156410217285156,21.285715103149414,20.907745361328125,21.226036071777344,20.67764812334124,907456,0.0,0.0,True
|
||||
2023-04-13 00:00:00+02:00,21.186250686645508,21.385181427001953,21.14646339416504,21.255876541137695,20.706715287158584,1096832,0.0,0.0,True
|
||||
2023-04-14 00:00:00+02:00,21.315555572509766,21.514488220214844,21.216089248657227,21.484647750854492,20.929576137559682,1071929,0.0,0.0,True
|
||||
2023-04-17 00:00:00+02:00,21.882511138916016,22.07149887084961,21.58411407470703,21.892459869384766,21.326852999624965,1508490,0.0,0.0,True
|
||||
2023-04-18 00:00:00+02:00,21.862619400024414,22.041658401489258,21.484647750854492,21.613954544067383,21.055546007610953,1127797,0.0,0.0,True
|
||||
2023-04-19 00:00:00+02:00,21.633846282958984,21.65374183654785,21.37523651123047,21.633846282958984,21.074922379654502,908843,0.0,0.0,True
|
||||
2023-04-20 00:00:00+02:00,21.68358039855957,21.68358039855957,21.484647750854492,21.6239013671875,21.065232890756718,810257,0.0,0.0,True
|
||||
2023-04-21 00:00:00+02:00,21.58411407470703,21.58411407470703,21.255876541137695,21.424968719482422,20.871437901296957,823291,0.0,0.0,True
|
||||
2023-04-24 00:00:00+02:00,21.385181427001953,21.703474044799805,21.295663833618164,21.633846282958984,21.074922379654502,882673,0.0,0.0,True
|
||||
2023-04-25 00:00:00+02:00,21.59406089782715,21.74325942993164,21.385181427001953,21.663686752319336,21.103993452099886,1318878,0.0,0.0,True
|
||||
2023-04-26 00:00:00+02:00,21.464754104614258,21.613954544067383,21.096731185913086,21.613954544067383,21.055546007610953,1135730,0.0,0.0,True
|
||||
2023-04-27 00:00:00+02:00,21.504541397094727,21.504541397094727,20.897798538208008,21.11662483215332,20.571062442589582,1167454,0.0,0.0,True
|
||||
2023-04-28 00:00:00+02:00,21.136518478393555,21.65374183654785,21.007211685180664,21.65374183654785,21.0943039632021,1480858,0.0,0.0,True
|
||||
2023-05-02 00:00:00+02:00,21.68358039855957,21.713420867919922,21.126571655273438,21.14646339416504,20.600129606406934,1146537,0.0,0.0,True
|
||||
2023-05-03 00:00:00+02:00,21.285715103149414,21.504541397094727,21.186250686645508,21.424968719482422,20.871437901296957,1054129,0.0,0.0,True
|
||||
2023-05-04 00:00:00+02:00,20.987319946289062,21.6437931060791,20.340789794921875,20.66902732849121,20.13502892780917,1741640,0.0,0.0,True
|
||||
2023-05-05 00:00:00+02:00,21.01715850830078,21.59406089782715,20.80828094482422,21.444862365722656,20.89082078772056,1420028,0.0,0.0,True
|
||||
2023-05-08 00:00:00+02:00,21.484647750854492,21.514488220214844,21.245929718017578,21.514488220214844,20.95864721000506,674713,0.0,0.0,True
|
||||
2023-05-09 00:00:00+02:00,21.663686752319336,21.663686752319336,21.17630386352539,21.444862365722656,20.89082078772056,853724,0.0,0.0,True
|
||||
2023-05-10 00:00:00+02:00,21.49459457397461,21.663686752319336,21.156410217285156,21.405075073242188,20.852060226377397,826931,0.0,0.0,True
|
||||
2023-05-11 00:00:00+02:00,21.464754104614258,21.633846282958984,21.106678009033203,21.37523651123047,20.82299175968404,1023400,0.0,0.0,True
|
||||
2023-05-12 00:00:00+02:00,21.37523651123047,21.43491554260254,21.206144332885742,21.37523651123047,20.822991759684037,847053,0.0,0.0,True
|
||||
2023-05-15 00:00:00+02:00,21.0469970703125,21.096731185913086,20.788387298583984,20.858013153076172,20.343019155002814,1023546,0.025099999999999997,0.0,True
|
||||
2023-05-16 00:00:00+02:00,20.7386531829834,20.76849365234375,20.281110763549805,20.310949325561523,19.80946174919578,1280267,0.0,0.0,True
|
||||
2023-05-17 00:00:00+02:00,20.201536178588867,20.57950782775879,20.092124938964844,20.549667358398438,20.042288055212353,1106539,0.0,0.0,True
|
||||
2023-05-18 00:00:00+02:00,20.72870635986328,20.818225860595703,20.539722442626953,20.678974151611328,20.168400441542484,704356,0.0,0.0,True
|
||||
2023-05-19 00:00:00+02:00,20.818225860595703,20.897798538208008,20.66902732849121,20.72870635986328,20.216904736568488,1030030,0.0,0.0,True
|
||||
2023-05-22 00:00:00+02:00,20.66902732849121,20.788387298583984,20.57950782775879,20.76849365234375,20.255711830376843,853879,0.0,0.0,True
|
||||
2023-05-23 00:00:00+02:00,20.748600006103516,20.80828094482422,20.66902732849121,20.79833221435547,20.284811562446574,779729,0.0,0.0,True
|
||||
2023-05-24 00:00:00+02:00,20.60934829711914,20.60934829711914,20.291057586669922,20.489988327026367,19.984082494760305,846847,0.0,0.0,True
|
||||
2023-05-25 00:00:00+02:00,20.51982879638672,20.51982879638672,19.962818145751953,20.01255226135254,19.518433946935552,1017197,0.0,0.0,True
|
||||
2023-05-26 00:00:00+02:00,20.141857147216797,20.26121711730957,19.885236740112305,20.191591262817383,19.693050628291687,1058894,0.0,0.0,True
|
||||
2023-05-29 00:00:00+02:00,20.301002502441406,20.340789794921875,20.181644439697266,20.26121711730957,19.760957454169773,295090,0.0,0.0,True
|
||||
2023-05-30 00:00:00+02:00,20.301002502441406,20.340789794921875,20.052337646484375,20.092124938964844,19.596040006135482,641576,0.0,0.0,True
|
||||
2023-05-31 00:00:00+02:00,19.77781105041504,19.77781105041504,19.184995651245117,19.427692413330078,18.948014171034597,3164263,0.0,0.0,True
|
||||
2023-06-01 00:00:00+02:00,19.614688873291016,19.698240280151367,19.475435256958008,19.68232536315918,19.196361688891155,876148,0.0,0.0,True
|
||||
2023-06-02 00:00:00+02:00,19.857385635375977,20.499935150146484,19.8255558013916,20.440256118774414,19.9355781997343,1069712,0.0,0.0,True
|
||||
2023-06-05 00:00:00+02:00,20.529775619506836,20.589454650878906,20.39052391052246,20.499935150146484,19.993783760186346,850280,0.0,0.0,True
|
||||
2023-06-06 00:00:00+02:00,20.489988327026367,20.66902732849121,20.38057518005371,20.66902732849121,20.158699176116443,646291,0.0,0.0,True
|
||||
2023-06-07 00:00:00+02:00,20.678974151611328,20.92763900756836,20.569562911987305,20.92763900756836,20.410928012985096,885388,0.0,0.0,True
|
||||
2023-06-08 00:00:00+02:00,20.877906799316406,21.514488220214844,20.877906799316406,21.186250686645508,20.66315278564536,1247924,0.0,0.0,True
|
||||
2023-06-09 00:00:00+02:00,21.126571655273438,21.17630386352539,20.46014976501465,20.818225860595703,20.30421612540285,1294412,0.0,0.0,True
|
||||
2023-06-12 00:00:00+02:00,20.887853622436523,21.08678436279297,20.80828094482422,21.05694580078125,20.537040399315227,932962,0.0,0.0,True
|
||||
2023-06-13 00:00:00+02:00,21.166357040405273,21.454809188842773,20.907745361328125,21.424968719482422,20.895977059557737,905912,0.0,0.0,True
|
||||
2023-06-14 00:00:00+02:00,21.862619400024414,21.882511138916016,21.424968719482422,21.514488220214844,20.9832864162879,1696595,0.0,0.0,True
|
||||
2023-06-15 00:00:00+02:00,21.474702835083008,21.474702835083008,21.01715850830078,21.355342864990234,20.82807023367965,932700,0.0,0.0,True
|
||||
2023-06-16 00:00:00+02:00,21.444862365722656,21.52443504333496,20.04239273071289,20.569562911987305,20.061690586064433,3430067,0.0,0.0,True
|
||||
2023-06-19 00:00:00+02:00,20.291057586669922,20.291057586669922,19.932979583740234,19.982711791992188,19.489328118553235,1208865,0.0,0.0,True
|
||||
2023-06-20 00:00:00+02:00,19.495328903198242,20.121965408325195,19.208866119384766,19.821577072143555,19.332173308543133,2053697,0.0,0.0,True
|
||||
2023-06-21 00:00:00+02:00,19.845449447631836,19.923032760620117,19.662431716918945,19.923032760620117,19.43112255810119,644074,0.0,0.0,True
|
||||
2023-06-22 00:00:00+02:00,19.749961853027344,20.022499084472656,19.68232536315918,19.797706604003906,19.30889352288735,667821,0.0,0.0,True
|
||||
2023-06-23 00:00:00+02:00,19.65447425842285,19.805662155151367,19.539094924926758,19.686304092407227,19.20023894369486,893260,0.0,0.0,True
|
||||
2023-06-26 00:00:00+02:00,19.757919311523438,20.032445907592773,19.65447425842285,19.982711791992188,19.489328118553235,793819,0.0,0.0,True
|
||||
2023-06-27 00:00:00+02:00,20.092124938964844,20.211484909057617,19.74200439453125,19.95287322998047,19.460228386483504,871227,0.0,0.0,True
|
||||
2023-06-28 00:00:00+02:00,20.112018585205078,20.151803970336914,19.865341186523438,19.95287322998047,19.460228386483504,911547,0.0,0.0,True
|
||||
2023-06-29 00:00:00+02:00,20.01255226135254,20.181644439697266,19.903139114379883,20.092124938964844,19.596040006135482,1053234,0.0,0.0,True
|
||||
2023-06-30 00:00:00+02:00,20.092124938964844,20.46014976501465,20.092124938964844,20.350736618041992,19.84826681089994,934560,0.0,0.0,True
|
||||
2023-07-03 00:00:00+02:00,20.301002502441406,20.499935150146484,20.181644439697266,20.26121711730957,19.760957454169773,652308,0.0,0.0,True
|
||||
2023-07-04 00:00:00+02:00,20.241323471069336,20.241323471069336,20.032445907592773,20.181644439697266,19.683351394969844,483753,0.0,0.0,True
|
||||
2023-07-05 00:00:00+02:00,20.07223129272461,20.201536178588867,20.002605438232422,20.092124938964844,19.596040006135482,692829,0.0,0.0,True
|
||||
2023-07-06 00:00:00+02:00,19.903139114379883,20.002605438232422,19.634580612182617,19.74200439453125,19.254565217239005,1098682,0.0,0.0,True
|
||||
2023-07-07 00:00:00+02:00,19.7181339263916,20.350736618041992,19.7181339263916,20.350736618041992,19.84826681089994,909321,0.0,0.0,True
|
||||
2023-07-10 00:00:00+02:00,20.221431732177734,20.48004150390625,20.201536178588867,20.241323471069336,19.741554923317693,599989,0.0,0.0,True
|
||||
2023-07-11 00:00:00+02:00,20.291057586669922,20.60934829711914,20.211484909057617,20.51982879638672,20.01318425893423,514723,0.0,0.0,True
|
||||
2023-07-12 00:00:00+02:00,20.569562911987305,21.126571655273438,20.529775619506836,21.066890716552734,20.54673963263707,903369,0.0,0.0,True
|
||||
2023-07-13 00:00:00+02:00,20.967424392700195,21.226036071777344,20.92763900756836,20.967424392700195,20.449729010480866,830319,0.0,0.0,True
|
||||
2023-07-14 00:00:00+02:00,20.877906799316406,20.897798538208008,20.301002502441406,20.301002502441406,19.799760483769738,959780,0.0,0.0,True
|
||||
2023-07-17 00:00:00+02:00,20.191591262817383,20.330842971801758,20.151803970336914,20.201536178588867,19.702749861613533,678639,0.0,0.0,True
|
||||
2023-07-18 00:00:00+02:00,20.211484909057617,20.410415649414062,20.112018585205078,20.410415649414062,19.906472371351985,696082,0.0,0.0,True
|
||||
2023-07-19 00:00:00+02:00,20.340789794921875,20.430309295654297,20.04239273071289,20.310949325561523,19.80946174919578,1027451,0.0,0.0,True
|
||||
2023-07-20 00:00:00+02:00,20.330842971801758,20.589454650878906,20.330842971801758,20.589454650878906,20.081091084812318,771530,0.0,0.0,True
|
||||
2023-07-21 00:00:00+02:00,20.569562911987305,20.758546829223633,20.499935150146484,20.639188766479492,20.129597411942516,532559,0.0,0.0,True
|
||||
2023-07-24 00:00:00+02:00,20.529775619506836,20.788387298583984,20.48004150390625,20.778440475463867,20.26541106369869,576946,0.0,0.0,True
|
||||
2023-07-25 00:00:00+02:00,20.80828094482422,21.156410217285156,20.7386531829834,21.14646339416504,20.6243477239412,815268,0.0,0.0,True
|
||||
2023-07-26 00:00:00+02:00,21.066890716552734,21.206144332885742,20.867958068847656,20.967424392700195,20.449729010480866,501060,0.0,0.0,True
|
||||
2023-07-27 00:00:00+02:00,21.01715850830078,21.43491554260254,20.967424392700195,21.39512825012207,20.866873263279615,1024169,0.0,0.0,True
|
||||
2023-07-28 00:00:00+02:00,21.30561065673828,21.802940368652344,21.255876541137695,21.802940368652344,21.264614985226284,1075428,0.0,0.0,True
|
||||
2023-07-31 00:00:00+02:00,21.802940368652344,21.912351608276367,21.663686752319336,21.703474044799805,21.167606395174275,1096731,0.0,0.0,True
|
||||
2023-08-01 00:00:00+02:00,21.59406089782715,21.604007720947266,21.424968719482422,21.424968719482422,20.895977059557737,660286,0.0,0.0,True
|
||||
2023-08-02 00:00:00+02:00,21.186250686645508,21.58411407470703,21.08678436279297,21.454809188842773,20.925080855835855,858203,0.0,0.0,True
|
||||
2023-08-03 00:00:00+02:00,21.673633575439453,21.78304672241211,20.01255226135254,20.499935150146484,19.993783760186346,1721865,0.0,0.0,True
|
||||
2023-08-04 00:00:00+02:00,20.66902732849121,20.718759536743164,20.39052391052246,20.659080505371094,20.148999942794596,610022,0.0,0.0,True
|
||||
2023-08-07 00:00:00+02:00,20.589454650878906,20.80828094482422,20.45020294189453,20.80828094482422,20.294514859976807,484065,0.0,0.0,True
|
||||
2023-08-08 00:00:00+02:00,20.688920974731445,20.818225860595703,20.589454650878906,20.678974151611328,20.168400441542484,420797,0.0,0.0,True
|
||||
2023-08-09 00:00:00+02:00,20.858013153076172,21.037052154541016,20.76849365234375,20.858013153076172,20.343019155002814,550545,0.0,0.0,True
|
||||
2023-08-10 00:00:00+02:00,20.977371215820312,21.126571655273438,20.858013153076172,20.997264862060547,20.478832806758987,468059,0.0,0.0,True
|
||||
2023-08-11 00:00:00+02:00,20.877906799316406,21.0271053314209,20.748600006103516,20.758546829223633,20.246010564950804,462374,0.0,0.0,True
|
||||
2023-08-14 00:00:00+02:00,20.7386531829834,20.848066329956055,20.66902732849121,20.7386531829834,20.22660600199453,668188,0.0,0.0,True
|
||||
2023-08-15 00:00:00+02:00,20.788387298583984,20.818225860595703,20.430309295654297,20.57950782775879,20.071389819386276,432414,0.0,0.0,True
|
||||
2023-08-16 00:00:00+02:00,20.539722442626953,20.76849365234375,20.539722442626953,20.70881462097168,20.197506269924798,544437,0.0,0.0,True
|
||||
2023-08-17 00:00:00+02:00,20.57950782775879,20.76849365234375,20.549667358398438,20.688920974731445,20.178101706968523,564871,0.0,0.0,True
|
||||
2023-08-18 00:00:00+02:00,20.688920974731445,20.70881462097168,20.291057586669922,20.38057518005371,19.877370607178058,693870,0.0,0.0,True
|
||||
2023-08-21 00:00:00+02:00,20.39052391052246,20.66902732849121,20.39052391052246,20.569562911987305,20.061690586064433,793311,0.0,0.0,True
|
||||
2023-08-22 00:00:00+02:00,20.599401473999023,20.907745361328125,20.5098819732666,20.76849365234375,20.255711830376843,650046,0.0,0.0,True
|
||||
2023-08-23 00:00:00+02:00,20.80828094482422,20.858013153076172,20.330842971801758,20.370630264282227,19.86766934175202,647211,0.0,0.0,True
|
||||
2023-08-24 00:00:00+02:00,20.45020294189453,20.599401473999023,20.291057586669922,20.330842971801758,19.828866312152055,475896,0.0,0.0,True
|
||||
2023-08-25 00:00:00+02:00,20.301002502441406,20.45020294189453,20.26121711730957,20.291057586669922,19.79006328255209,318928,0.0,0.0,True
|
||||
2023-08-28 00:00:00+02:00,20.42036247253418,20.549667358398438,20.42036247253418,20.499935150146484,19.993783760186346,332741,0.0,0.0,True
|
||||
2023-08-29 00:00:00+02:00,20.66902732849121,20.897798538208008,20.66902732849121,20.838119506835938,20.323616624150734,523138,0.0,0.0,True
|
||||
2023-08-30 00:00:00+02:00,20.838119506835938,21.007211685180664,20.778440475463867,20.907745361328125,20.39152345002882,394929,0.0,0.0,True
|
||||
2023-08-31 00:00:00+02:00,20.947532653808594,21.36528968811035,20.92763900756836,21.265823364257812,20.740760876949484,2323236,0.0,0.0,True
|
||||
2023-09-01 00:00:00+02:00,21.255876541137695,21.9322452545166,21.255876541137695,21.87256622314453,21.332523843208566,966179,0.0,0.0,True
|
||||
2023-09-04 00:00:00+02:00,21.981977462768555,22.021764755249023,21.544328689575195,21.58411407470703,21.05119121006179,643546,0.0,0.0,True
|
||||
2023-09-05 00:00:00+02:00,21.504541397094727,21.78304672241211,21.424968719482422,21.6239013671875,21.08999627176595,541345,0.0,0.0,True
|
||||
2023-09-06 00:00:00+02:00,21.544328689575195,22.111284255981445,21.504541397094727,22.09139060974121,21.545945586268864,851678,0.0,0.0,True
|
||||
2023-09-07 00:00:00+02:00,21.882511138916016,21.90240478515625,21.424968719482422,21.464754104614258,20.9347800891577,700314,0.0,0.0,True
|
||||
2023-09-08 00:00:00+02:00,21.574167251586914,21.574167251586914,20.887853622436523,21.235984802246094,20.711659112775557,719356,0.0,0.0,True
|
||||
2023-09-11 00:00:00+02:00,21.345396041870117,21.564220428466797,21.315555572509766,21.52443504333496,20.992985649609746,524078,0.0,0.0,True
|
||||
2023-09-12 00:00:00+02:00,21.58411407470703,21.6239013671875,21.11662483215332,21.11662483215332,20.595245959767272,772781,0.0,0.0,True
|
||||
2023-09-13 00:00:00+02:00,21.0469970703125,21.36528968811035,20.76849365234375,20.818225860595703,20.30421612540285,691035,0.0,0.0,True
|
||||
2023-09-14 00:00:00+02:00,20.887853622436523,21.196197509765625,20.629241943359375,21.126571655273438,20.604947225193314,578423,0.0,0.0,True
|
||||
2023-09-15 00:00:00+02:00,21.295663833618164,21.952138900756836,21.295663833618164,21.84272575378418,21.30341801482625,2234985,0.0,0.0,True
|
||||
2023-09-18 00:00:00+02:00,21.802940368652344,21.84272575378418,21.673633575439453,21.713420867919922,21.177307660600313,856277,0.0,0.0,True
|
||||
2023-09-19 00:00:00+02:00,21.6437931060791,21.6437931060791,21.39512825012207,21.415021896362305,20.8862737620275,685505,0.0,0.0,True
|
||||
2023-09-20 00:00:00+02:00,21.52443504333496,21.792993545532227,21.504541397094727,21.74325942993164,21.206407392670044,752488,0.0,0.0,True
|
||||
2023-09-21 00:00:00+02:00,21.534381866455078,21.574167251586914,21.0271053314209,21.186250686645508,20.66315278564536,722196,0.0,0.0,True
|
||||
2023-09-22 00:00:00+02:00,21.08678436279297,21.295663833618164,20.95747947692871,21.096731185913086,20.575843428915192,535977,0.0,0.0,True
|
||||
2023-09-25 00:00:00+02:00,21.037052154541016,21.17630386352539,20.529775619506836,20.788387298583984,20.275112329124727,678523,0.0,0.0,True
|
||||
2023-09-26 00:00:00+02:00,20.72870635986328,20.72870635986328,20.410415649414062,20.489988327026367,19.984082494760305,999281,0.0,0.0,True
|
||||
2023-09-27 00:00:00+02:00,20.559614181518555,20.66902732849121,20.440256118774414,20.569562911987305,20.061690586064433,679654,0.0,0.0,True
|
||||
2023-09-28 00:00:00+02:00,20.57950782775879,20.858013153076172,20.42036247253418,20.80828094482422,20.294514859976807,791858,0.0,0.0,True
|
||||
2023-09-29 00:00:00+02:00,20.977371215820312,21.07683753967285,20.778440475463867,20.858013153076172,20.343019155002814,1368070,0.0,0.0,True
|
||||
2023-10-02 00:00:00+02:00,20.877906799316406,20.95747947692871,20.38057518005371,20.489988327026367,19.984082494760305,921943,0.0,0.0,True
|
||||
2023-10-03 00:00:00+02:00,20.45020294189453,20.559614181518555,20.241323471069336,20.430309295654297,19.92587693430826,870202,0.0,0.0,True
|
||||
2023-10-04 00:00:00+02:00,20.340789794921875,20.629241943359375,20.23137664794922,20.301002502441406,19.799760483769738,1412955,0.0,0.0,True
|
||||
2023-10-05 00:00:00+02:00,20.301002502441406,20.410415649414062,20.151803970336914,20.23137664794922,19.731855689995847,552761,0.0,0.0,True
|
||||
2023-10-06 00:00:00+02:00,20.271163940429688,20.489988327026367,20.17169761657715,20.370630264282227,19.86766934175202,824653,0.0,0.0,True
|
||||
2023-10-09 00:00:00+02:00,20.201536178588867,20.26121711730957,19.817598342895508,20.201536178588867,19.702749861613533,857112,0.0,0.0,True
|
||||
2023-10-10 00:00:00+02:00,20.310949325561523,20.619295120239258,20.281110763549805,20.470096588134766,19.964679963908225,881954,0.0,0.0,True
|
||||
2023-10-11 00:00:00+02:00,20.32089614868164,20.629241943359375,20.32089614868164,20.440256118774414,19.9355781997343,612797,0.0,0.0,True
|
||||
2023-10-12 00:00:00+02:00,20.569562911987305,20.688920974731445,20.271163940429688,20.32089614868164,19.819165046726013,484462,0.0,0.0,True
|
||||
2023-10-13 00:00:00+02:00,20.211484909057617,20.470096588134766,20.211484909057617,20.301002502441406,19.799760483769738,538324,0.0,0.0,True
|
||||
2023-10-16 00:00:00+02:00,20.340789794921875,20.489988327026367,20.26121711730957,20.310949325561523,19.80946174919578,495104,0.0,0.0,True
|
||||
2023-10-17 00:00:00+02:00,20.241323471069336,20.301002502441406,19.9130859375,20.221431732177734,19.722156456674004,618131,0.0,0.0,True
|
||||
2023-10-18 00:00:00+02:00,20.191591262817383,20.23137664794922,19.881256103515625,19.881256103515625,19.390378868995178,559829,0.0,0.0,True
|
||||
2023-10-19 00:00:00+02:00,19.714153289794922,19.84147071838379,19.551029205322266,19.630603790283203,19.145914702254906,708805,0.0,0.0,True
|
||||
2023-10-20 00:00:00+02:00,19.49930763244629,19.54705047607422,19.296396255493164,19.296396255493164,18.819959093094223,760144,0.0,0.0,True
|
||||
2023-10-23 00:00:00+02:00,19.3162899017334,19.344141006469727,19.005956649780273,19.16908073425293,18.69578736627014,652032,0.0,0.0,True
|
||||
2023-10-24 00:00:00+02:00,19.101444244384766,19.232738494873047,18.994020462036133,19.11735725402832,18.645342411738085,565349,0.0,0.0,True
|
||||
2023-10-25 00:00:00+02:00,19.133272171020508,19.184995651245117,18.882619857788086,19.093486785888672,18.622060593978105,597757,0.0,0.0,True
|
||||
2023-10-26 00:00:00+02:00,18.882619857788086,19.507265090942383,18.834875106811523,19.403820037841797,18.924732353274617,756208,0.0,0.0,True
|
||||
2023-10-27 00:00:00+02:00,19.519201278686523,19.75394058227539,19.20488739013672,19.20488739013672,18.730711108962204,767302,0.0,0.0,True
|
||||
2023-10-30 00:00:00+01:00,19.296396255493164,19.54705047607422,19.296396255493164,19.45156478881836,18.97129802089877,755454,0.0,0.0,True
|
||||
2023-10-31 00:00:00+01:00,19.455543518066406,19.972766876220703,19.443607330322266,19.84147071838379,19.351575839395213,1249155,0.0,0.0,True
|
||||
2023-11-01 00:00:00+01:00,19.903139114379883,20.04239273071289,19.551029205322266,19.618667602539062,19.134274809427016,645054,0.0,0.0,True
|
||||
2023-11-02 00:00:00+01:00,19.734046936035156,20.410415649414062,19.726089477539062,20.141857147216797,19.64454430116149,1414951,0.0,0.0,True
|
||||
2023-11-03 00:00:00+01:00,19.877277374267578,20.211484909057617,19.165102005004883,19.51124382019043,19.02950154924662,1786173,0.0,0.0,True
|
||||
2023-11-06 00:00:00+01:00,19.515222549438477,19.78179168701172,19.304353713989258,19.531137466430664,19.0489040800987,1141224,0.0,0.0,True
|
||||
2023-11-07 00:00:00+01:00,19.42371368408203,19.535114288330078,19.25263214111328,19.35209846496582,18.874285366638368,719557,0.0,0.0,True
|
||||
2023-11-08 00:00:00+01:00,19.228759765625,19.427692413330078,19.093486785888672,19.320268630981445,18.843242942958398,829203,0.0,0.0,True
|
||||
2023-11-09 00:00:00+01:00,19.308332443237305,19.903139114379883,19.308332443237305,19.574901580810547,19.09158842871076,1169455,0.0,0.0,True
|
||||
2023-11-10 00:00:00+01:00,19.479415893554688,19.761898040771484,19.244674682617188,19.761898040771484,19.273967748091085,991826,0.0,0.0,True
|
||||
2023-11-13 00:00:00+01:00,19.773834228515625,19.857385635375977,19.531137466430664,19.734046936035156,19.246804611319014,980360,0.0,0.0,True
|
||||
2023-11-14 00:00:00+01:00,19.79372787475586,20.410415649414062,19.78974723815918,20.340789794921875,19.838567577578093,892672,0.0,0.0,True
|
||||
2023-11-15 00:00:00+01:00,20.36068344116211,20.917692184448242,20.291057586669922,20.917692184448242,20.40122471545486,1168610,0.0,0.0,True
|
||||
2023-11-16 00:00:00+01:00,20.79833221435547,21.07683753967285,20.549667358398438,20.549667358398438,20.042288055212353,755625,0.0,0.0,True
|
||||
2023-11-17 00:00:00+01:00,20.549667358398438,20.848066329956055,20.549667358398438,20.559614181518555,20.05198932063839,784037,0.0,0.0,True
|
||||
2023-11-20 00:00:00+01:00,20.589454650878906,20.887853622436523,20.51982879638672,20.72870635986328,20.216904736568488,946072,0.0,0.0,True
|
||||
2023-11-21 00:00:00+01:00,20.688920974731445,20.82817268371582,20.470096588134766,20.629241943359375,20.119896146516478,1185330,0.0,0.0,True
|
||||
2023-11-22 00:00:00+01:00,20.629241943359375,20.838119506835938,20.559614181518555,20.599401473999023,20.09079438234255,1261386,0.0,0.0,True
|
||||
2023-11-23 00:00:00+01:00,20.599401473999023,20.76849365234375,20.599401473999023,20.7386531829834,20.22660600199453,633558,0.0,0.0,True
|
||||
2023-11-24 00:00:00+01:00,20.778440475463867,20.92763900756836,20.72870635986328,20.92763900756836,20.410928012985096,719180,0.0,0.0,True
|
||||
2023-11-27 00:00:00+01:00,20.887853622436523,20.907745361328125,20.51982879638672,20.57950782775879,20.071389819386276,1094505,0.0,0.0,True
|
||||
2023-11-28 00:00:00+01:00,20.529775619506836,20.66902732849121,20.330842971801758,20.60934829711914,20.100495647768593,1053370,0.0,0.0,True
|
||||
2023-11-29 00:00:00+01:00,20.60934829711914,21.037052154541016,20.569562911987305,20.977371215820312,20.459430275906907,957061,0.0,0.0,True
|
||||
2023-11-30 00:00:00+01:00,20.947532653808594,21.27577018737793,20.818225860595703,21.11662483215332,20.595245959767272,2370750,0.0,0.0,True
|
||||
2023-12-01 00:00:00+01:00,21.166357040405273,21.6437931060791,21.166357040405273,21.604007720947266,21.070595773018066,1195222,0.0,0.0,True
|
||||
2023-12-04 00:00:00+01:00,21.484647750854492,21.94219207763672,21.464754104614258,21.74325942993164,21.206407392670044,1089262,0.0,0.0,True
|
||||
2023-12-05 00:00:00+01:00,21.6239013671875,21.9322452545166,21.59406089782715,21.882511138916016,21.34222307653041,1150906,0.0,0.0,True
|
||||
2023-12-06 00:00:00+01:00,21.882511138916016,22.081443786621094,21.84272575378418,22.041658401489258,21.497441291242858,1090639,0.0,0.0,True
|
||||
2023-12-07 00:00:00+01:00,22.081443786621094,22.489255905151367,22.041658401489258,22.359949111938477,21.80787365645936,1596696,0.0,0.0,True
|
||||
2023-12-08 00:00:00+01:00,22.330108642578125,22.479307174682617,21.991924285888672,22.35000228881836,21.798170358929127,1410130,0.0,0.0,True
|
||||
2023-12-11 00:00:00+01:00,19.450000762939453,23.649999618530273,17.895000457763672,20.6200008392334,20.110883764412478,8998324,0.0,0.0,True
|
||||
2023-12-12 00:00:00+01:00,20.790000915527344,22.3700008392334,20.75,22.139999389648438,21.593352545029667,3236690,0.0,0.0,True
|
||||
2023-12-13 00:00:00+01:00,22.489999771118164,24.530000686645508,22.399999618530273,23.950000762939453,23.358663812210377,2215354,0.0,0.0,True
|
||||
2023-12-14 00:00:00+01:00,24.5,25.010000228881836,23.950000762939453,24.540000915527344,23.934096789159938,1535694,0.0,0.0,True
|
||||
2023-12-15 00:00:00+01:00,24.8799991607666,25.420000076293945,24.600000381469727,25.40999984741211,24.782616120433715,2385553,0.0,0.0,True
|
||||
2023-12-18 00:00:00+01:00,25.649999618530273,26.969999313354492,25.489999771118164,26.1299991607666,25.484838174410278,965441,0.0,0.0,True
|
||||
2023-12-19 00:00:00+01:00,26.290000915527344,27.399999618530273,26.200000762939453,27.209999084472656,26.53817328747932,908754,0.0,0.0,True
|
||||
2023-12-20 00:00:00+01:00,27.3700008392334,27.469999313354492,26.350000381469727,26.350000381469727,25.699408056340648,821654,0.0,0.0,True
|
||||
2023-12-21 00:00:00+01:00,26.239999771118164,26.3700008392334,25.760000228881836,26.049999237060547,25.406813501746218,744197,0.0,0.0,True
|
||||
2023-12-22 00:00:00+01:00,26.1200008392334,26.510000228881836,26.049999237060547,26.239999771118164,25.59212311537546,358134,0.0,0.0,True
|
||||
2023-12-27 00:00:00+01:00,26.639999389648438,26.729999542236328,26.299999237060547,26.729999542236328,26.070023219390748,398784,0.0,0.0,True
|
||||
2023-12-28 00:00:00+01:00,26.899999618530273,27.200000762939453,26.899999618530273,27.190000534057617,26.518669151417498,306879,0.0,0.0,True
|
||||
2023-12-29 00:00:00+01:00,27.219999313354492,27.959999084472656,27.219999313354492,27.729999542236328,27.045333659795727,508827,0.0,0.0,True
|
||||
2024-01-02 00:00:00+01:00,28.059999465942383,28.600000381469727,27.520000457763672,28.030000686645508,27.337928214390157,395002,0.0,0.0,True
|
||||
2024-01-03 00:00:00+01:00,28.110000610351562,28.15999984741211,27.170000076293945,27.43000030517578,26.75274113730549,517626,0.0,0.0,True
|
||||
2024-01-04 00:00:00+01:00,27.5,28.110000610351562,27.5,28.09000015258789,27.396446718888203,353356,0.0,0.0,True
|
||||
2024-01-05 00:00:00+01:00,28.079999923706055,28.469999313354492,28.0,28.329999923706055,27.630518704776197,426440,0.0,0.0,True
|
||||
2024-01-08 00:00:00+01:00,28.290000915527344,28.329999923706055,27.540000915527344,28.0,27.308667946089034,503233,0.0,0.0,True
|
||||
2024-01-09 00:00:00+01:00,27.190000534057617,27.549999237060547,27.079999923706055,27.299999237060547,26.62595002817429,592677,0.0,0.0,True
|
||||
2024-01-10 00:00:00+01:00,27.100000381469727,27.170000076293945,26.350000381469727,26.350000381469727,25.699408056340648,692877,0.0,0.0,True
|
||||
2024-01-11 00:00:00+01:00,26.389999389648438,26.559999465942383,25.889999389648438,26.0,25.35804706527908,631805,0.0,0.0,True
|
||||
2024-01-12 00:00:00+01:00,26.639999389648438,26.860000610351562,26.06999969482422,26.139999389648438,25.49459024244119,803481,0.0,0.0,True
|
||||
2024-01-15 00:00:00+01:00,25.059999465942383,25.329999923706055,25.0,25.299999237060547,24.690631866455078,726646,0.016200000000000003,0.0,False
|
||||
2024-01-16 00:00:00+01:00,25.149999618530273,25.200000762939453,24.579999923706055,24.989999771118164,24.388099670410156,493029,0.0,0.0,False
|
||||
2024-01-17 00:00:00+01:00,24.700000762939453,24.729999542236328,23.989999771118164,24.260000228881836,23.675682067871094,646371,0.0,0.0,False
|
||||
2024-01-18 00:00:00+01:00,24.200000762939453,24.239999771118164,23.530000686645508,23.530000686645508,22.963266372680664,686723,0.0,0.0,False
|
||||
2024-01-19 00:00:00+01:00,23.670000076293945,24.25,23.670000076293945,24.049999237060547,23.470739364624023,679303,0.0,0.0,False
|
||||
2024-01-22 00:00:00+01:00,24.299999237060547,24.770000457763672,24.079999923706055,24.760000228881836,24.163639068603516,282294,0.0,0.0,False
|
||||
2024-01-23 00:00:00+01:00,25.200000762939453,25.450000762939453,24.90999984741211,25.3799991607666,24.768705368041992,397643,0.0,0.0,False
|
||||
2024-01-24 00:00:00+01:00,25.600000381469727,25.6299991607666,24.75,24.75,24.153881072998047,564082,0.0,0.0,False
|
||||
2024-01-25 00:00:00+01:00,24.84000015258789,25.760000228881836,24.799999237060547,25.600000381469727,24.983407974243164,401178,0.0,0.0,False
|
||||
2024-01-26 00:00:00+01:00,25.690000534057617,26.959999084472656,25.6200008392334,26.40999984741211,25.773897171020508,712857,0.0,0.0,False
|
||||
2024-01-29 00:00:00+01:00,26.5,26.549999237060547,25.760000228881836,25.760000228881836,25.139554977416992,375526,0.0,0.0,False
|
||||
2024-01-30 00:00:00+01:00,25.8799991607666,26.049999237060547,25.610000610351562,25.690000534057617,25.071239471435547,339731,0.0,0.0,False
|
||||
2024-01-31 00:00:00+01:00,25.850000381469727,26.1299991607666,25.440000534057617,25.440000534057617,24.827260971069336,1756316,0.0,0.0,False
|
||||
2024-02-01 00:00:00+01:00,25.329999923706055,25.5,24.530000686645508,24.59000015258789,23.99773406982422,398800,0.0,0.0,False
|
||||
2024-02-02 00:00:00+01:00,24.899999618530273,24.979999542236328,24.40999984741211,24.40999984741211,23.82206916809082,418661,0.0,0.0,False
|
||||
2024-02-05 00:00:00+01:00,24.440000534057617,24.56999969482422,23.6299991607666,23.649999618530273,23.080373764038086,640546,0.0,0.0,False
|
||||
2024-02-06 00:00:00+01:00,23.739999771118164,23.81999969482422,22.8799991607666,23.469999313354492,22.904708862304688,800098,0.0,0.0,False
|
||||
2024-02-07 00:00:00+01:00,23.200000762939453,23.309999465942383,22.489999771118164,22.639999389648438,22.09469985961914,896379,0.0,0.0,False
|
||||
2024-02-08 00:00:00+01:00,22.799999237060547,23.1299991607666,22.690000534057617,23.0,22.446029663085938,622376,0.0,0.0,False
|
||||
2024-02-09 00:00:00+01:00,22.5,22.739999771118164,22.209999084472656,22.209999084472656,21.67505645751953,783024,0.0,0.0,False
|
||||
2024-02-12 00:00:00+01:00,22.450000762939453,22.899999618530273,22.290000915527344,22.84000015258789,22.289884567260742,443790,0.0,0.0,False
|
||||
2024-02-13 00:00:00+01:00,22.860000610351562,23.34000015258789,22.719999313354492,23.190000534057617,22.631454467773438,530025,0.0,0.0,False
|
||||
2024-02-14 00:00:00+01:00,23.06999969482422,23.5,22.90999984741211,23.489999771118164,22.92422866821289,452602,0.0,0.0,False
|
||||
2024-02-15 00:00:00+01:00,23.6200008392334,24.170000076293945,23.579999923706055,23.940000534057617,23.36338996887207,423885,0.0,0.0,False
|
||||
2024-02-16 00:00:00+01:00,24.280000686645508,24.420000076293945,23.770000457763672,24.020000457763672,23.441463470458984,445071,0.0,0.0,False
|
||||
2024-02-19 00:00:00+01:00,24.110000610351562,24.139999389648438,23.690000534057617,23.690000534057617,23.11941146850586,334433,0.0,0.0,False
|
||||
2024-02-20 00:00:00+01:00,23.770000457763672,24.09000015258789,23.489999771118164,24.09000015258789,23.509777069091797,306827,0.0,0.0,False
|
||||
2024-02-21 00:00:00+01:00,23.850000381469727,24.040000915527344,23.5,24.040000915527344,23.460981369018555,431924,0.0,0.0,False
|
||||
2024-02-22 00:00:00+01:00,24.229999542236328,24.399999618530273,24.010000228881836,24.219999313354492,23.63664436340332,366743,0.0,0.0,False
|
||||
2024-02-23 00:00:00+01:00,24.239999771118164,24.6200008392334,23.860000610351562,23.959999084472656,23.38290786743164,266603,0.0,0.0,False
|
||||
2024-02-26 00:00:00+01:00,23.959999084472656,23.959999084472656,23.270000457763672,23.479999542236328,22.91446876525879,316183,0.0,0.0,False
|
||||
2024-02-27 00:00:00+01:00,23.540000915527344,23.889999389648438,23.329999923706055,23.75,23.17796516418457,284263,0.0,0.0,False
|
||||
2024-02-28 00:00:00+01:00,23.829999923706055,24.059999465942383,23.559999465942383,23.6200008392334,23.051097869873047,344714,0.0,0.0,False
|
||||
2024-02-29 00:00:00+01:00,23.600000381469727,23.6299991607666,23.329999923706055,23.5,22.93398666381836,601749,0.0,0.0,False
|
||||
2024-03-01 00:00:00+01:00,23.6299991607666,24.530000686645508,23.59000015258789,24.200000762939453,23.617128372192383,445507,0.0,0.0,False
|
||||
2024-03-04 00:00:00+01:00,24.1200008392334,24.229999542236328,22.989999771118164,23.3799991607666,22.816877365112305,469234,0.0,0.0,False
|
||||
2024-03-05 00:00:00+01:00,23.329999923706055,23.579999923706055,23.079999923706055,23.579999923706055,23.012060165405273,321295,0.0,0.0,False
|
||||
2024-03-06 00:00:00+01:00,23.579999923706055,24.100000381469727,23.549999237060547,23.549999237060547,22.9827823638916,516710,0.0,0.0,False
|
||||
2024-03-07 00:00:00+01:00,23.389999389648438,23.670000076293945,23.100000381469727,23.5,22.93398666381836,371579,0.0,0.0,False
|
||||
2024-03-08 00:00:00+01:00,23.520000457763672,23.770000457763672,22.969999313354492,23.739999771118164,23.1682071685791,426367,0.0,0.0,False
|
||||
2024-03-11 00:00:00+01:00,23.68000030517578,24.100000381469727,23.450000762939453,24.100000381469727,23.5195369720459,437456,0.0,0.0,False
|
||||
2024-03-12 00:00:00+01:00,24.299999237060547,25.450000762939453,24.059999465942383,25.25,24.64183807373047,794906,0.0,0.0,False
|
||||
2024-03-13 00:00:00+01:00,24.100000381469727,26.010000228881836,23.950000762939453,24.549999237060547,23.958696365356445,844838,0.0,0.0,False
|
||||
2024-03-14 00:00:00+01:00,24.440000534057617,24.729999542236328,23.649999618530273,23.81999969482422,23.246280670166016,643203,0.0,0.0,False
|
||||
2024-03-15 00:00:00+01:00,23.850000381469727,24.579999923706055,23.229999542236328,23.229999542236328,22.670490264892578,1376963,0.0,0.0,False
|
||||
2024-03-18 00:00:00+01:00,23.229999542236328,23.6299991607666,23.030000686645508,23.440000534057617,22.87543296813965,406545,0.0,0.0,False
|
||||
2024-03-19 00:00:00+01:00,23.149999618530273,23.75,23.040000915527344,23.670000076293945,23.09989356994629,429140,0.0,0.0,False
|
||||
2024-03-20 00:00:00+01:00,23.639999389648438,24.110000610351562,23.5,24.030000686645508,23.451223373413086,308989,0.0,0.0,False
|
||||
2024-03-21 00:00:00+01:00,24.18000030517578,24.479999542236328,24.030000686645508,24.15999984741211,23.57809066772461,415990,0.0,0.0,False
|
||||
2024-03-22 00:00:00+01:00,24.139999389648438,24.719999313354492,23.84000015258789,24.540000915527344,23.948938369750977,295245,0.0,0.0,False
|
||||
2024-03-25 00:00:00+01:00,24.549999237060547,25.100000381469727,24.520000457763672,25.059999465942383,24.45641326904297,348983,0.0,0.0,False
|
||||
2024-03-26 00:00:00+01:00,25.030000686645508,25.09000015258789,24.299999237060547,24.549999237060547,23.958696365356445,323207,0.0,0.0,False
|
||||
2024-03-27 00:00:00+01:00,24.459999084472656,24.969999313354492,24.31999969482422,24.969999313354492,24.368581771850586,203281,0.0,0.0,False
|
||||
2024-03-28 00:00:00+01:00,25.020000457763672,25.360000610351562,24.700000762939453,25.299999237060547,24.690631866455078,292668,0.0,0.0,False
|
||||
2024-04-02 00:00:00+02:00,25.350000381469727,25.799999237060547,25.299999237060547,25.600000381469727,24.983407974243164,302238,0.0,0.0,False
|
||||
2024-04-03 00:00:00+02:00,25.68000030517578,26.8799991607666,25.6299991607666,26.690000534057617,26.047155380249023,448326,0.0,0.0,False
|
||||
2024-04-04 00:00:00+02:00,28.5,29.190000534057617,27.709999084472656,27.709999084472656,27.042585372924805,1493843,0.0,0.0,False
|
||||
2024-04-05 00:00:00+02:00,27.350000381469727,27.959999084472656,27.010000228881836,27.350000381469727,26.69125747680664,540908,0.0,0.0,False
|
||||
2024-04-08 00:00:00+02:00,27.399999618530273,28.309999465942383,27.34000015258789,28.270000457763672,27.589099884033203,487088,0.0,0.0,False
|
||||
2024-04-09 00:00:00+02:00,28.350000381469727,28.43000030517578,28.049999237060547,28.200000762939453,27.52078628540039,253999,0.0,0.0,False
|
||||
2024-04-10 00:00:00+02:00,28.34000015258789,29.40999984741211,28.1200008392334,28.639999389648438,27.950185775756836,735134,0.0,0.0,False
|
||||
2024-04-11 00:00:00+02:00,28.93000030517578,29.260000228881836,28.649999618530273,28.959999084472656,28.262479782104492,306645,0.0,0.0,False
|
||||
2024-04-12 00:00:00+02:00,29.399999618530273,29.799999237060547,29.170000076293945,29.5,28.789474487304688,437731,0.0,0.0,False
|
||||
2024-04-15 00:00:00+02:00,29.100000381469727,29.850000381469727,29.0,29.450000762939453,28.740678787231445,388339,0.0,0.0,False
|
||||
2024-04-16 00:00:00+02:00,29.200000762939453,29.350000381469727,28.780000686645508,28.780000686645508,28.086816787719727,434787,0.0,0.0,False
|
||||
2024-04-17 00:00:00+02:00,28.780000686645508,29.989999771118164,28.760000228881836,29.799999237060547,29.082246780395508,352161,0.0,0.0,False
|
||||
2024-04-18 00:00:00+02:00,29.899999618530273,30.700000762939453,29.780000686645508,30.649999618530273,29.911775588989258,347317,0.0,0.0,False
|
||||
2024-04-19 00:00:00+02:00,30.5,31.040000915527344,28.34000015258789,30.75,30.009366989135742,697878,0.0,0.0,False
|
||||
2024-04-22 00:00:00+02:00,30.81999969482422,31.600000381469727,30.770000457763672,31.56999969482422,30.809616088867188,401308,0.0,0.0,False
|
||||
2024-04-23 00:00:00+02:00,31.579999923706055,31.65999984741211,30.049999237060547,31.0,30.253345489501953,471634,0.0,0.0,False
|
||||
2024-04-24 00:00:00+02:00,30.950000762939453,31.75,30.90999984741211,31.200000762939453,30.448528289794922,307607,0.0,0.0,False
|
||||
2024-04-25 00:00:00+02:00,31.299999237060547,31.329999923706055,29.670000076293945,29.75,29.0334529876709,478021,0.0,0.0,False
|
||||
2024-04-26 00:00:00+02:00,30.25,30.719999313354492,29.959999084472656,30.18000030517578,29.453096389770508,331898,0.0,0.0,False
|
||||
2024-04-29 00:00:00+02:00,30.209999084472656,30.899999618530273,30.209999084472656,30.850000381469727,30.106958389282227,225725,0.0,0.0,False
|
||||
2024-04-30 00:00:00+02:00,30.899999618530273,31.18000030517578,30.290000915527344,30.40999984741211,29.677555084228516,232054,0.0,0.0,False
|
||||
2024-05-02 00:00:00+02:00,30.40999984741211,30.600000381469727,29.709999084472656,30.5,29.76538848876953,390674,0.0,0.0,False
|
||||
2024-05-03 00:00:00+02:00,29.56999969482422,30.299999237060547,29.5,30.139999389648438,29.414058685302734,364126,0.0,0.0,False
|
||||
2024-05-06 00:00:00+02:00,30.290000915527344,30.989999771118164,30.139999389648438,30.420000076293945,29.687314987182617,273816,0.0,0.0,False
|
||||
2024-05-07 00:00:00+02:00,31.600000381469727,35.25,31.360000610351562,34.7599983215332,33.92278289794922,1075584,0.0,0.0,False
|
||||
2024-05-08 00:00:00+02:00,34.34000015258789,36.619998931884766,33.43000030517578,34.68000030517578,33.84471130371094,1057246,0.0,0.0,False
|
||||
2024-05-09 00:00:00+02:00,34.650001525878906,35.33000183105469,34.209999084472656,34.38999938964844,33.56169509887695,262471,0.0,0.0,False
|
||||
2024-05-10 00:00:00+02:00,34.790000915527344,34.939998626708984,33.58000183105469,33.650001525878906,32.83951950073242,223080,0.0,0.0,False
|
||||
2024-05-13 00:00:00+02:00,33.5,34.459999084472656,33.33000183105469,34.310001373291016,33.48362350463867,273103,0.0,0.0,False
|
||||
2024-05-14 00:00:00+02:00,34.220001220703125,34.52000045776367,33.560001373291016,34.52000045776367,33.68856430053711,279550,0.0,0.0,False
|
||||
2024-05-15 00:00:00+02:00,34.630001068115234,34.900001525878906,33.75,34.099998474121094,33.27867889404297,242453,0.0,0.0,False
|
||||
2024-05-16 00:00:00+02:00,34.13999938964844,34.13999938964844,33.04999923706055,33.599998474121094,32.79072189331055,235321,0.0,0.0,False
|
||||
2024-05-17 00:00:00+02:00,32.84000015258789,34.06999969482422,32.59000015258789,34.06999969482422,33.2494010925293,339910,0.0,0.0,False
|
||||
2024-05-20 00:00:00+02:00,34.400001525878906,34.400001525878906,33.70000076293945,34.04999923706055,33.229881286621094,164887,0.0,0.0,False
|
||||
2024-05-21 00:00:00+02:00,33.97999954223633,34.130001068115234,33.31999969482422,33.31999969482422,32.5174674987793,171162,0.0,0.0,False
|
||||
2024-05-22 00:00:00+02:00,33.29999923706055,34.189998626708984,32.93000030517578,34.189998626708984,33.366512298583984,345186,0.0,0.0,False
|
||||
2024-05-23 00:00:00+02:00,34.189998626708984,34.75,34.150001525878906,34.470001220703125,33.6397705078125,301874,0.0,0.0,False
|
||||
2024-05-24 00:00:00+02:00,34.29999923706055,35.040000915527344,34.060001373291016,34.52000045776367,33.68856430053711,297474,0.0,0.0,False
|
||||
2024-05-27 00:00:00+02:00,34.52000045776367,34.900001525878906,34.25,34.5,33.669044494628906,145496,0.0,0.0,False
|
||||
2024-05-28 00:00:00+02:00,34.459999084472656,34.540000915527344,33.81999969482422,34.400001525878906,33.57145690917969,239174,0.0,0.0,False
|
||||
2024-05-29 00:00:00+02:00,34.400001525878906,34.439998626708984,33.900001525878906,34.220001220703125,33.395790100097656,245711,0.0,0.0,False
|
||||
2024-05-30 00:00:00+02:00,34.61000061035156,34.61000061035156,33.75,34.310001373291016,33.48362350463867,270049,0.0,0.0,False
|
||||
2024-05-31 00:00:00+02:00,34.25,34.650001525878906,33.45000076293945,33.630001068115234,32.81999969482422,348292,0.0,0.0,False
|
||||
2024-06-03 00:00:00+02:00,33.20000076293945,33.290000915527344,31.81999969482422,31.829999923706055,31.829999923706055,271111,0.81,0.0,False
|
||||
2024-06-04 00:00:00+02:00,31.780000686645508,31.860000610351562,31.260000228881836,31.649999618530273,31.649999618530273,345119,0.0,0.0,False
|
||||
2024-06-05 00:00:00+02:00,31.770000457763672,31.940000534057617,31.270000457763672,31.270000457763672,31.270000457763672,371491,0.0,0.0,False
|
||||
2024-06-06 00:00:00+02:00,31.489999771118164,31.510000228881836,30.600000381469727,30.920000076293945,30.920000076293945,325501,0.0,0.0,False
|
||||
2024-06-07 00:00:00+02:00,30.90999984741211,31.209999084472656,30.600000381469727,30.969999313354492,30.969999313354492,161556,0.0,0.0,False
|
||||
2024-06-10 00:00:00+02:00,30.850000381469727,31.739999771118164,30.729999542236328,31.739999771118164,31.739999771118164,265293,0.0,0.0,False
|
||||
2024-06-11 00:00:00+02:00,31.639999389648438,32.529998779296875,31.639999389648438,32.349998474121094,32.349998474121094,424271,0.0,0.0,False
|
||||
2024-06-12 00:00:00+02:00,32.40999984741211,33.04999923706055,32.40999984741211,32.81999969482422,32.81999969482422,244552,0.0,0.0,False
|
||||
2024-06-13 00:00:00+02:00,32.54999923706055,32.54999923706055,31.709999084472656,31.780000686645508,31.780000686645508,302052,0.0,0.0,False
|
||||
2024-06-14 00:00:00+02:00,31.600000381469727,31.6299991607666,30.34000015258789,30.790000915527344,30.790000915527344,342157,0.0,0.0,False
|
||||
2024-06-17 00:00:00+02:00,30.920000076293945,31.479999542236328,30.889999389648438,31.34000015258789,31.34000015258789,273690,0.0,0.0,False
|
||||
2024-06-18 00:00:00+02:00,31.579999923706055,31.690000534057617,31.06999969482422,31.229999542236328,31.229999542236328,218534,0.0,0.0,False
|
||||
2024-06-19 00:00:00+02:00,31.260000228881836,31.81999969482422,31.200000762939453,31.350000381469727,31.350000381469727,175454,0.0,0.0,False
|
||||
2024-06-20 00:00:00+02:00,31.31999969482422,32.11000061035156,31.31999969482422,31.709999084472656,31.709999084472656,296995,0.0,0.0,False
|
||||
2024-06-21 00:00:00+02:00,31.860000610351562,32.04999923706055,31.559999465942383,31.719999313354492,31.719999313354492,2005373,0.0,0.0,False
|
||||
2024-06-24 00:00:00+02:00,31.700000762939453,33.630001068115234,31.700000762939453,33.06999969482422,33.06999969482422,347579,0.0,0.0,False
|
||||
2024-06-25 00:00:00+02:00,33.0,33.34000015258789,31.90999984741211,31.90999984741211,31.90999984741211,241894,0.0,0.0,False
|
||||
2024-06-26 00:00:00+02:00,31.899999618530273,32.349998474121094,31.649999618530273,31.8700008392334,31.8700008392334,267568,0.0,0.0,False
|
||||
2024-06-27 00:00:00+02:00,32.29999923706055,33.0,32.20000076293945,32.900001525878906,32.900001525878906,182682,0.0,0.0,False
|
||||
2024-06-28 00:00:00+02:00,32.95000076293945,33.060001373291016,32.31999969482422,32.869998931884766,32.869998931884766,277611,0.0,0.0,False
|
||||
2024-07-01 00:00:00+02:00,33.29999923706055,33.4900016784668,32.72999954223633,33.4900016784668,33.4900016784668,206747,0.0,0.0,False
|
||||
2024-07-02 00:00:00+02:00,33.5,34.0,33.13999938964844,34.0,34.0,231379,0.0,0.0,False
|
||||
2024-07-03 00:00:00+02:00,33.95000076293945,34.13999938964844,33.47999954223633,34.13999938964844,34.13999938964844,262502,0.0,0.0,False
|
||||
2024-07-04 00:00:00+02:00,34.0,34.20000076293945,33.540000915527344,34.060001373291016,34.060001373291016,130465,0.0,0.0,False
|
||||
2024-07-05 00:00:00+02:00,34.060001373291016,34.279998779296875,33.5099983215332,33.5099983215332,33.5099983215332,212429,0.0,0.0,False
|
||||
2024-07-08 00:00:00+02:00,33.400001525878906,33.95000076293945,32.81999969482422,33.95000076293945,33.95000076293945,194477,0.0,0.0,False
|
||||
2024-07-09 00:00:00+02:00,33.790000915527344,34.060001373291016,32.290000915527344,32.5099983215332,32.5099983215332,364262,0.0,0.0,False
|
||||
2024-07-10 00:00:00+02:00,32.29999923706055,32.38999938964844,31.75,32.040000915527344,32.040000915527344,207620,0.0,0.0,False
|
||||
2024-07-11 00:00:00+02:00,32.11000061035156,32.599998474121094,32.06999969482422,32.349998474121094,32.349998474121094,159663,0.0,0.0,False
|
||||
2024-07-12 00:00:00+02:00,32.29999923706055,32.93000030517578,32.29999923706055,32.59000015258789,32.59000015258789,116583,0.0,0.0,False
|
||||
2024-07-15 00:00:00+02:00,32.459999084472656,32.689998626708984,31.899999618530273,32.279998779296875,32.279998779296875,123588,0.0,0.0,False
|
||||
2024-07-16 00:00:00+02:00,32.20000076293945,32.65999984741211,31.940000534057617,32.45000076293945,32.45000076293945,88377,0.0,0.0,False
|
||||
2024-07-17 00:00:00+02:00,32.72999954223633,33.939998626708984,32.040000915527344,33.939998626708984,33.939998626708984,222062,0.0,0.0,False
|
||||
2024-07-18 00:00:00+02:00,34.0,34.93000030517578,33.79999923706055,34.63999938964844,34.63999938964844,400707,0.0,0.0,False
|
||||
2024-07-19 00:00:00+02:00,34.290000915527344,34.36000061035156,33.529998779296875,34.0099983215332,34.0099983215332,188494,0.0,0.0,False
|
||||
2024-07-22 00:00:00+02:00,34.349998474121094,34.5,33.66999816894531,34.13999938964844,34.13999938964844,144759,0.0,0.0,False
|
||||
2024-07-23 00:00:00+02:00,33.95000076293945,34.02000045776367,33.5,33.83000183105469,33.83000183105469,99602,0.0,0.0,False
|
||||
2024-07-24 00:00:00+02:00,33.54999923706055,33.97999954223633,33.459999084472656,33.5099983215332,33.5099983215332,118200,0.0,0.0,False
|
||||
2024-07-25 00:00:00+02:00,33.400001525878906,33.75,32.43000030517578,33.41999816894531,33.41999816894531,143724,0.0,0.0,False
|
||||
2024-07-26 00:00:00+02:00,33.09000015258789,33.439998626708984,32.650001525878906,33.2599983215332,33.2599983215332,150065,0.0,0.0,False
|
||||
2024-07-29 00:00:00+02:00,33.25,33.560001373291016,33.06999969482422,33.18000030517578,33.18000030517578,101941,0.0,0.0,False
|
||||
2024-07-30 00:00:00+02:00,33.0,33.619998931884766,32.86000061035156,33.18000030517578,33.18000030517578,142743,0.0,0.0,False
|
||||
2024-07-31 00:00:00+02:00,33.849998474121094,34.0,32.20000076293945,32.52000045776367,32.52000045776367,561976,0.0,0.0,False
|
||||
2024-08-01 00:00:00+02:00,32.13999938964844,32.599998474121094,31.190000534057617,31.469999313354492,31.469999313354492,275048,0.0,0.0,False
|
||||
2024-08-02 00:00:00+02:00,31.229999542236328,31.760000228881836,30.860000610351562,30.860000610351562,30.860000610351562,265760,0.0,0.0,False
|
||||
2024-08-05 00:00:00+02:00,30.100000381469727,30.479999542236328,29.469999313354492,29.940000534057617,29.940000534057617,473460,0.0,0.0,False
|
||||
2024-08-06 00:00:00+02:00,30.5,31.010000228881836,30.040000915527344,30.190000534057617,30.190000534057617,264982,0.0,0.0,False
|
||||
2024-08-07 00:00:00+02:00,30.510000228881836,31.229999542236328,30.3799991607666,30.889999389648438,30.889999389648438,178311,0.0,0.0,False
|
||||
2024-08-08 00:00:00+02:00,30.799999237060547,30.959999084472656,30.40999984741211,30.799999237060547,30.799999237060547,172146,0.0,0.0,False
|
||||
2024-08-09 00:00:00+02:00,30.90999984741211,31.520000457763672,30.90999984741211,31.15999984741211,31.15999984741211,179785,0.0,0.0,False
|
||||
2024-08-12 00:00:00+02:00,31.299999237060547,31.690000534057617,30.59000015258789,30.59000015258789,30.59000015258789,132932,0.0,0.0,False
|
||||
2024-08-13 00:00:00+02:00,30.690000534057617,31.040000915527344,30.360000610351562,30.600000381469727,30.600000381469727,103593,0.0,0.0,False
|
||||
2024-08-14 00:00:00+02:00,30.649999618530273,30.68000030517578,30.059999465942383,30.479999542236328,30.479999542236328,209068,0.0,0.0,False
|
||||
2024-08-15 00:00:00+02:00,30.549999237060547,31.09000015258789,30.450000762939453,30.920000076293945,30.920000076293945,125365,0.0,0.0,False
|
||||
2024-08-16 00:00:00+02:00,30.940000534057617,31.1200008392334,30.729999542236328,30.8799991607666,30.8799991607666,141253,0.0,0.0,False
|
||||
2024-08-19 00:00:00+02:00,31.030000686645508,31.299999237060547,30.670000076293945,31.030000686645508,31.030000686645508,180272,0.0,0.0,False
|
||||
2024-08-20 00:00:00+02:00,31.170000076293945,31.170000076293945,30.469999313354492,30.530000686645508,30.530000686645508,152575,0.0,0.0,False
|
||||
2024-08-21 00:00:00+02:00,30.530000686645508,31.020000457763672,30.530000686645508,30.969999313354492,30.969999313354492,128994,0.0,0.0,False
|
||||
2024-08-22 00:00:00+02:00,30.979999542236328,31.3799991607666,30.780000686645508,31.229999542236328,31.229999542236328,87006,0.0,0.0,False
|
||||
2024-08-23 00:00:00+02:00,31.18000030517578,31.540000915527344,31.18000030517578,31.270000457763672,31.270000457763672,84423,0.0,0.0,False
|
||||
2024-08-26 00:00:00+02:00,31.149999618530273,31.459999084472656,30.829999923706055,31.030000686645508,31.030000686645508,72965,0.0,0.0,False
|
||||
2024-08-27 00:00:00+02:00,30.90999984741211,31.360000610351562,30.809999465942383,31.139999389648438,31.139999389648438,102326,0.0,0.0,False
|
||||
2024-08-28 00:00:00+02:00,31.139999389648438,31.190000534057617,30.540000915527344,30.93000030517578,30.93000030517578,133750,0.0,0.0,False
|
||||
2024-08-29 00:00:00+02:00,30.81999969482422,31.25,30.81999969482422,31.079999923706055,31.079999923706055,110738,0.0,0.0,False
|
||||
2024-08-30 00:00:00+02:00,31.190000534057617,31.829999923706055,31.079999923706055,31.700000762939453,31.700000762939453,222082,0.0,0.0,False
|
||||
2024-09-02 00:00:00+02:00,31.739999771118164,32.36000061035156,31.469999313354492,32.18000030517578,32.18000030517578,137822,0.0,0.0,False
|
||||
2024-09-03 00:00:00+02:00,32.04999923706055,32.2400016784668,31.469999313354492,31.520000457763672,31.520000457763672,115050,0.0,0.0,False
|
||||
2024-09-04 00:00:00+02:00,31.100000381469727,31.739999771118164,31.030000686645508,31.559999465942383,31.559999465942383,110471,0.0,0.0,False
|
||||
2024-09-05 00:00:00+02:00,31.34000015258789,32.310001373291016,31.34000015258789,31.670000076293945,31.670000076293945,230413,0.0,0.0,False
|
||||
2024-09-06 00:00:00+02:00,31.489999771118164,31.8700008392334,31.18000030517578,31.209999084472656,31.209999084472656,163894,0.0,0.0,False
|
||||
2024-09-09 00:00:00+02:00,31.5,31.729999542236328,31.280000686645508,31.649999618530273,31.649999618530273,150347,0.0,0.0,False
|
||||
2024-09-10 00:00:00+02:00,31.59000015258789,32.040000915527344,30.8700008392334,30.8700008392334,30.8700008392334,177060,0.0,0.0,False
|
||||
2024-09-11 00:00:00+02:00,30.93000030517578,32.06999969482422,30.93000030517578,31.049999237060547,31.049999237060547,253253,0.0,0.0,False
|
||||
2024-09-12 00:00:00+02:00,31.049999237060547,31.3799991607666,30.809999465942383,30.809999465942383,30.809999465942383,198487,0.0,0.0,False
|
||||
2024-09-13 00:00:00+02:00,30.809999465942383,31.6299991607666,30.809999465942383,31.3700008392334,31.3700008392334,160154,0.0,0.0,False
|
||||
2024-09-16 00:00:00+02:00,31.270000457763672,31.469999313354492,31.100000381469727,31.450000762939453,31.450000762939453,112962,0.0,0.0,False
|
||||
2024-09-17 00:00:00+02:00,31.719999313354492,32.75,31.719999313354492,32.75,32.75,181018,0.0,0.0,False
|
||||
2024-09-18 00:00:00+02:00,32.81999969482422,33.84000015258789,32.38999938964844,33.72999954223633,33.72999954223633,208825,0.0,0.0,False
|
||||
2024-09-19 00:00:00+02:00,34.119998931884766,34.689998626708984,33.84000015258789,34.58000183105469,34.58000183105469,292983,0.0,0.0,False
|
||||
2024-09-20 00:00:00+02:00,34.599998474121094,34.599998474121094,33.93000030517578,34.279998779296875,34.279998779296875,547234,0.0,0.0,False
|
||||
2024-09-23 00:00:00+02:00,34.22999954223633,34.68000030517578,34.11000061035156,34.369998931884766,34.369998931884766,148293,0.0,0.0,False
|
||||
2024-09-24 00:00:00+02:00,34.709999084472656,35.13999938964844,34.279998779296875,34.279998779296875,34.279998779296875,214647,0.0,0.0,False
|
||||
2024-09-25 00:00:00+02:00,34.279998779296875,34.83000183105469,33.58000183105469,33.58000183105469,33.58000183105469,194543,0.0,0.0,False
|
||||
2024-09-26 00:00:00+02:00,34.0,34.119998931884766,33.650001525878906,34.119998931884766,34.119998931884766,198143,0.0,0.0,False
|
||||
2024-09-27 00:00:00+02:00,34.2400016784668,35.02000045776367,34.130001068115234,34.63999938964844,34.63999938964844,196448,0.0,0.0,False
|
||||
2024-09-30 00:00:00+02:00,34.150001525878906,35.45000076293945,34.0,35.20000076293945,35.20000076293945,261067,0.0,0.0,False
|
||||
2024-10-01 00:00:00+02:00,35.20000076293945,35.88999938964844,35.18000030517578,35.61000061035156,35.61000061035156,218502,0.0,0.0,False
|
||||
2024-10-02 00:00:00+02:00,35.61000061035156,36.810001373291016,35.45000076293945,36.310001373291016,36.310001373291016,185328,0.0,0.0,False
|
||||
2024-10-03 00:00:00+02:00,36.22999954223633,36.619998931884766,36.209999084472656,36.310001373291016,36.310001373291016,246827,0.0,0.0,False
|
||||
2024-10-04 00:00:00+02:00,36.209999084472656,37.560001373291016,36.13999938964844,37.5099983215332,37.5099983215332,298766,0.0,0.0,False
|
||||
2024-10-07 00:00:00+02:00,37.5,37.5099983215332,36.47999954223633,36.91999816894531,36.91999816894531,161195,0.0,0.0,False
|
||||
2024-10-08 00:00:00+02:00,36.7599983215332,36.7599983215332,35.66999816894531,35.93000030517578,35.93000030517578,144993,0.0,0.0,False
|
||||
2024-10-09 00:00:00+02:00,35.86000061035156,36.52000045776367,35.400001525878906,36.369998931884766,36.369998931884766,123249,0.0,0.0,False
|
||||
2024-10-10 00:00:00+02:00,36.619998931884766,37.0,36.439998626708984,36.959999084472656,36.959999084472656,127939,0.0,0.0,False
|
||||
2024-10-11 00:00:00+02:00,36.650001525878906,37.349998474121094,36.560001373291016,37.150001525878906,37.150001525878906,110000,0.0,0.0,False
|
||||
2024-10-14 00:00:00+02:00,37.349998474121094,38.0,37.0,38.0,38.0,215775,0.0,0.0,False
|
||||
2024-10-15 00:00:00+02:00,38.0,38.72999954223633,37.7400016784668,38.43000030517578,38.43000030517578,289899,0.0,0.0,False
|
||||
2024-10-16 00:00:00+02:00,38.5,39.31999969482422,38.310001373291016,39.31999969482422,39.31999969482422,351315,0.0,0.0,False
|
||||
2024-10-17 00:00:00+02:00,39.27000045776367,39.310001373291016,37.95000076293945,38.439998626708984,38.439998626708984,336837,0.0,0.0,False
|
||||
2024-10-18 00:00:00+02:00,38.209999084472656,39.369998931884766,37.939998626708984,39.349998474121094,39.349998474121094,284589,0.0,0.0,False
|
||||
2024-10-21 00:00:00+02:00,39.11000061035156,39.13999938964844,38.43000030517578,39.099998474121094,39.099998474121094,176237,0.0,0.0,False
|
||||
2024-10-22 00:00:00+02:00,39.119998931884766,39.369998931884766,38.63999938964844,38.900001525878906,38.900001525878906,219984,0.0,0.0,False
|
||||
2024-10-23 00:00:00+02:00,38.70000076293945,38.86000061035156,37.790000915527344,38.79999923706055,38.79999923706055,212351,0.0,0.0,False
|
||||
2024-10-24 00:00:00+02:00,38.70000076293945,38.939998626708984,38.36000061035156,38.68000030517578,38.68000030517578,118090,0.0,0.0,False
|
||||
2024-10-25 00:00:00+02:00,38.630001068115234,38.849998474121094,38.04999923706055,38.560001373291016,38.560001373291016,164039,0.0,0.0,False
|
||||
2024-10-28 00:00:00+01:00,38.560001373291016,38.81999969482422,37.84000015258789,38.25,38.25,156263,0.0,0.0,False
|
||||
2024-10-29 00:00:00+01:00,38.25,38.88999938964844,38.029998779296875,38.31999969482422,38.31999969482422,213012,0.0,0.0,False
|
||||
2024-10-30 00:00:00+01:00,37.75,38.04999923706055,37.029998779296875,37.029998779296875,37.029998779296875,397551,0.0,0.0,False
|
||||
2024-10-31 00:00:00+01:00,37.0,37.310001373291016,36.34000015258789,37.060001373291016,37.060001373291016,281687,0.0,0.0,False
|
||||
2024-11-01 00:00:00+01:00,36.84000015258789,37.43000030517578,36.84000015258789,37.2400016784668,37.2400016784668,81048,0.0,0.0,False
|
||||
2024-11-04 00:00:00+01:00,37.060001373291016,37.79999923706055,37.040000915527344,37.560001373291016,37.560001373291016,82632,0.0,0.0,False
|
||||
2024-11-05 00:00:00+01:00,37.560001373291016,37.95000076293945,37.369998931884766,37.95000076293945,37.95000076293945,199518,0.0,0.0,False
|
||||
2024-11-06 00:00:00+01:00,38.20000076293945,38.900001525878906,34.91999816894531,34.91999816894531,34.91999816894531,469899,0.0,0.0,False
|
||||
2024-11-07 00:00:00+01:00,34.08000183105469,34.900001525878906,33.72999954223633,33.72999954223633,33.72999954223633,380050,0.0,0.0,False
|
||||
2024-11-08 00:00:00+01:00,33.61000061035156,33.91999816894531,33.29999923706055,33.54999923706055,33.54999923706055,389420,0.0,0.0,False
|
||||
2024-11-11 00:00:00+01:00,33.810001373291016,34.31999969482422,33.130001068115234,33.130001068115234,33.130001068115234,233145,0.0,0.0,False
|
||||
2024-11-12 00:00:00+01:00,32.79999923706055,33.029998779296875,31.670000076293945,31.709999084472656,31.709999084472656,284709,0.0,0.0,False
|
||||
2024-11-13 00:00:00+01:00,31.780000686645508,32.11000061035156,31.360000610351562,31.510000228881836,31.510000228881836,208626,0.0,0.0,False
|
||||
2024-11-14 00:00:00+01:00,31.600000381469727,31.8799991607666,31.34000015258789,31.40999984741211,31.40999984741211,193374,0.0,0.0,False
|
||||
2024-11-15 00:00:00+01:00,31.309999465942383,32.5,31.309999465942383,32.22999954223633,32.22999954223633,130866,0.0,0.0,False
|
||||
2024-11-18 00:00:00+01:00,32.20000076293945,32.72999954223633,32.08000183105469,32.130001068115234,32.130001068115234,94641,0.0,0.0,False
|
||||
2024-11-19 00:00:00+01:00,32.099998474121094,32.650001525878906,31.06999969482422,31.920000076293945,31.920000076293945,159142,0.0,0.0,False
|
||||
|
@@ -1,741 +0,0 @@
|
||||
Datetime,Open,High,Low,Close,Adj Close,Volume,Dividends,Stock Splits
|
||||
2022-01-03 00:00:00+01:00,20.400468826293945,20.80828094482422,20.400468826293945,20.629241943359375,11.042256355285645,559352,0.0,0.0
|
||||
2022-01-04 00:00:00+01:00,20.649133682250977,20.897798538208008,20.5098819732666,20.848066329956055,11.15938663482666,930594,0.0,0.0
|
||||
2022-01-05 00:00:00+01:00,20.897798538208008,21.126571655273438,20.838119506835938,21.126571655273438,11.308463096618652,572100,0.0,0.0
|
||||
2022-01-06 00:00:00+01:00,20.887853622436523,21.126571655273438,20.599401473999023,20.967424392700195,11.22327709197998,532086,0.0,0.0
|
||||
2022-01-07 00:00:00+01:00,21.007211685180664,21.186250686645508,20.867958068847656,21.126571655273438,11.308463096618652,698666,0.0,0.0
|
||||
2022-01-10 00:00:00+01:00,21.186250686645508,21.245929718017578,20.997264862060547,21.05694580078125,11.271194458007812,972438,0.0,0.0
|
||||
2022-01-11 00:00:00+01:00,21.226036071777344,21.514488220214844,21.226036071777344,21.37523651123047,11.441566467285156,894602,0.0,0.0
|
||||
2022-01-12 00:00:00+01:00,21.564220428466797,21.604007720947266,21.0469970703125,21.216089248657227,11.356379508972168,838352,0.0,0.0
|
||||
2022-01-13 00:00:00+01:00,20.897798538208008,21.14646339416504,20.897798538208008,21.14646339416504,12.180268287658691,514241,1.5,0.0
|
||||
2022-01-14 00:00:00+01:00,20.897798538208008,21.066890716552734,20.80828094482422,21.0271053314209,12.111517906188965,708327,0.0,0.0
|
||||
2022-01-17 00:00:00+01:00,21.106678009033203,21.633846282958984,21.0469970703125,21.554275512695312,12.415164947509766,947841,0.0,0.0
|
||||
2022-01-18 00:00:00+01:00,21.454809188842773,21.484647750854492,21.156410217285156,21.405075073242188,12.32922649383545,966355,0.0,0.0
|
||||
2022-01-19 00:00:00+01:00,21.37523651123047,21.822832107543945,21.295663833618164,21.78304672241211,12.5469388961792,1597827,0.0,0.0
|
||||
2022-01-20 00:00:00+01:00,21.802940368652344,22.111284255981445,21.544328689575195,21.981977462768555,12.661521911621094,1563328,0.0,0.0
|
||||
2022-01-21 00:00:00+01:00,21.74325942993164,21.94219207763672,21.415021896362305,21.65374183654785,12.472458839416504,1539782,0.0,0.0
|
||||
2022-01-24 00:00:00+01:00,21.484647750854492,21.58411407470703,20.887853622436523,20.997264862060547,12.094330787658691,1334240,0.0,0.0
|
||||
2022-01-25 00:00:00+01:00,21.156410217285156,21.186250686645508,20.877906799316406,20.917692184448242,12.048497200012207,1198631,0.0,0.0
|
||||
2022-01-26 00:00:00+01:00,20.997264862060547,21.72336769104004,20.997264862060547,21.415021896362305,12.334957122802734,913216,0.0,0.0
|
||||
2022-01-27 00:00:00+01:00,21.11662483215332,21.862619400024414,21.0469970703125,21.6437931060791,12.466727256774902,765306,0.0,0.0
|
||||
2022-01-28 00:00:00+01:00,21.554275512695312,21.65374183654785,21.126571655273438,21.484647750854492,12.375060081481934,1109097,0.0,0.0
|
||||
2022-01-31 00:00:00+01:00,21.6239013671875,21.65374183654785,21.066890716552734,21.186250686645508,12.20318603515625,999557,0.0,0.0
|
||||
2022-02-01 00:00:00+01:00,21.27577018737793,21.405075073242188,21.05694580078125,21.11662483215332,12.163081169128418,732572,0.0,0.0
|
||||
2022-02-02 00:00:00+01:00,21.52443504333496,22.021764755249023,21.454809188842773,21.753206253051758,12.52974796295166,1195479,0.0,0.0
|
||||
2022-02-03 00:00:00+01:00,21.773099899291992,21.892459869384766,21.6239013671875,21.773099899291992,12.541208267211914,906159,0.0,0.0
|
||||
2022-02-04 00:00:00+01:00,21.87256622314453,21.87256622314453,21.345396041870117,21.424968719482422,12.340685844421387,763864,0.0,0.0
|
||||
2022-02-07 00:00:00+01:00,21.574167251586914,21.574167251586914,21.265823364257812,21.415021896362305,12.334957122802734,382854,0.0,0.0
|
||||
2022-02-08 00:00:00+01:00,21.36528968811035,21.78304672241211,21.36528968811035,21.713420867919922,12.506832122802734,1006721,0.0,0.0
|
||||
2022-02-09 00:00:00+01:00,21.812885284423828,21.991924285888672,21.733312606811523,21.981977462768555,12.661521911621094,893571,0.0,0.0
|
||||
2022-02-10 00:00:00+01:00,22.021764755249023,22.210750579833984,21.962085723876953,22.041658401489258,12.69589614868164,851844,0.0,0.0
|
||||
2022-02-11 00:00:00+01:00,21.882511138916016,22.06155014038086,21.713420867919922,21.882511138916016,12.604228019714355,893486,0.0,0.0
|
||||
2022-02-14 00:00:00+01:00,21.514488220214844,21.514488220214844,20.818225860595703,21.14646339416504,12.180268287658691,1234728,0.0,0.0
|
||||
2022-02-15 00:00:00+01:00,21.007211685180664,21.713420867919922,20.967424392700195,21.673633575439453,12.483914375305176,687285,0.0,0.0
|
||||
2022-02-16 00:00:00+01:00,21.713420867919922,22.06155014038086,21.713420867919922,22.06155014038086,12.707353591918945,798177,0.0,0.0
|
||||
2022-02-17 00:00:00+01:00,22.021764755249023,22.081443786621094,21.763153076171875,21.832778930664062,12.575582504272461,684218,0.0,0.0
|
||||
2022-02-18 00:00:00+01:00,21.832778930664062,21.892459869384766,21.385181427001953,21.544328689575195,12.409436225891113,737030,0.0,0.0
|
||||
2022-02-21 00:00:00+01:00,21.673633575439453,21.68358039855957,20.92763900756836,21.126571655273438,12.168810844421387,677844,0.0,0.0
|
||||
2022-02-22 00:00:00+01:00,20.529775619506836,21.196197509765625,20.32089614868164,20.95747947692871,12.07141399383545,1273455,0.0,0.0
|
||||
2022-02-23 00:00:00+01:00,21.415021896362305,21.862619400024414,20.987319946289062,21.216089248657227,12.220373153686523,1732461,0.0,0.0
|
||||
2022-02-24 00:00:00+01:00,20.48004150390625,20.877906799316406,19.51124382019043,19.70221710205078,11.348389625549316,2560976,0.0,0.0
|
||||
2022-02-25 00:00:00+01:00,19.903139114379883,20.291057586669922,19.475435256958008,20.201536178588867,11.635994911193848,1423396,0.0,0.0
|
||||
2022-02-28 00:00:00+01:00,19.773834228515625,19.903139114379883,19.308332443237305,19.837491989135742,11.42630672454834,1569727,0.0,0.0
|
||||
2022-03-01 00:00:00+01:00,19.77781105041504,19.95287322998047,18.73938751220703,18.73938751220703,10.793803215026855,1308216,0.0,0.0
|
||||
2022-03-02 00:00:00+01:00,18.536476135253906,19.12929344177246,18.17840003967285,18.966169357299805,10.924428939819336,1739856,0.0,0.0
|
||||
2022-03-03 00:00:00+01:00,19.001977920532227,19.077571868896484,18.297758102416992,18.361417770385742,10.576093673706055,834767,0.0,0.0
|
||||
2022-03-04 00:00:00+01:00,18.13463592529297,18.14259147644043,16.893299102783203,17.05642318725586,9.824422836303711,2249030,0.0,0.0
|
||||
2022-03-07 00:00:00+01:00,16.384033203125,17.10814666748047,15.516690254211426,16.380054473876953,9.43483829498291,2250820,0.0,0.0
|
||||
2022-03-08 00:00:00+01:00,16.21295166015625,16.941043853759766,16.16520881652832,16.805768966674805,9.680047988891602,1388112,0.0,0.0
|
||||
2022-03-09 00:00:00+01:00,17.207611083984375,18.22614288330078,17.17976188659668,18.22614288330078,10.498176574707031,1580329,0.0,0.0
|
||||
2022-03-10 00:00:00+01:00,18.38926887512207,18.429054260253906,17.44632911682129,17.696983337402344,10.19338321685791,1037018,0.0,0.0
|
||||
2022-03-11 00:00:00+01:00,17.88397979736328,18.369373321533203,17.585582733154297,17.943660736083984,10.335468292236328,985960,0.0,0.0
|
||||
2022-03-14 00:00:00+01:00,18.285823822021484,18.747344970703125,18.250015258789062,18.52056312561035,10.66776180267334,963701,0.0,0.0
|
||||
2022-03-15 00:00:00+01:00,19.79372787475586,19.893192291259766,17.99538230895996,18.15452766418457,10.456927299499512,2685295,0.0,0.0
|
||||
2022-03-16 00:00:00+01:00,18.78713035583496,18.9741268157959,18.369373321533203,18.76723861694336,10.809845924377441,1321768,0.0,0.0
|
||||
2022-03-17 00:00:00+01:00,18.89853286743164,18.966169357299805,18.433032989501953,18.854768753051758,10.860261917114258,1124314,0.0,0.0
|
||||
2022-03-18 00:00:00+01:00,18.894554138183594,18.98606300354004,18.47281837463379,18.7990665435791,10.828177452087402,1809744,0.0,0.0
|
||||
2022-03-21 00:00:00+01:00,18.7990665435791,19.15714454650879,18.763259887695312,18.91046905517578,10.892345428466797,703039,0.0,0.0
|
||||
2022-03-22 00:00:00+01:00,18.966169357299805,19.184995651245117,18.85079002380371,19.05767822265625,10.977137565612793,715772,0.0,0.0
|
||||
2022-03-23 00:00:00+01:00,19.121337890625,19.15714454650879,18.671751022338867,18.671751022338867,10.754844665527344,1351532,0.0,0.0
|
||||
2022-03-24 00:00:00+01:00,18.659814834594727,18.731430053710938,18.234100341796875,18.30173683166504,10.541718482971191,1286093,0.0,0.0
|
||||
2022-03-25 00:00:00+01:00,18.405181884765625,18.47281837463379,18.170442581176758,18.285823822021484,10.532552719116211,726494,0.0,0.0
|
||||
2022-03-28 00:00:00+02:00,18.393245697021484,18.759281158447266,18.329587936401367,18.433032989501953,10.61734390258789,837768,0.0,0.0
|
||||
2022-03-29 00:00:00+02:00,18.72745132446289,19.256610870361328,18.687665939331055,19.16908073425293,11.041304588317871,917861,0.0,0.0
|
||||
2022-03-30 00:00:00+02:00,19.15714454650879,19.15714454650879,18.46088218688965,18.50862693786621,10.66088581085205,823527,0.0,0.0
|
||||
2022-03-31 00:00:00+02:00,18.50862693786621,18.822938919067383,17.768600463867188,17.796449661254883,10.250675201416016,1780930,0.0,0.0
|
||||
2022-04-01 00:00:00+02:00,17.895915985107422,18.102806091308594,17.880001068115234,17.880001068115234,10.29880142211914,751206,0.0,0.0
|
||||
2022-04-04 00:00:00+02:00,17.92376708984375,17.991403579711914,17.517946243286133,17.79247283935547,10.248384475708008,836607,0.0,0.0
|
||||
2022-04-05 00:00:00+02:00,17.77655792236328,17.975488662719727,17.382671356201172,17.617412567138672,10.147550582885742,842142,0.0,0.0
|
||||
2022-04-06 00:00:00+02:00,17.577625274658203,17.625368118286133,16.87340545654297,17.016637802124023,9.801506996154785,1380130,0.0,0.0
|
||||
2022-04-07 00:00:00+02:00,17.10814666748047,17.382671356201172,16.865449905395508,16.89727783203125,9.732755661010742,857449,0.0,0.0
|
||||
2022-04-08 00:00:00+02:00,17.191696166992188,17.382671356201172,16.99674415588379,17.191696166992188,9.90234088897705,913588,0.0,0.0
|
||||
2022-04-11 00:00:00+02:00,17.219547271728516,17.549774169921875,17.036529541015625,17.203632354736328,9.909215927124023,1067867,0.0,0.0
|
||||
2022-04-12 00:00:00+02:00,17.00868034362793,17.565689086914062,16.833620071411133,17.565689086914062,10.117757797241211,1285128,0.0,0.0
|
||||
2022-04-13 00:00:00+02:00,17.438373565673828,17.525903701782227,17.267290115356445,17.506010055541992,10.083382606506348,697328,0.0,0.0
|
||||
2022-04-14 00:00:00+02:00,17.58160400390625,17.657197952270508,17.406543731689453,17.513967514038086,10.087966918945312,587256,0.0,0.0
|
||||
2022-04-19 00:00:00+02:00,17.54181671142578,17.69300651550293,17.418479919433594,17.517946243286133,10.090258598327637,962344,0.0,0.0
|
||||
2022-04-20 00:00:00+02:00,17.633325576782227,17.967531204223633,17.609453201293945,17.768600463867188,10.234634399414062,675733,0.0,0.0
|
||||
2022-04-21 00:00:00+02:00,17.860109329223633,18.38926887512207,17.860109329223633,18.28980255126953,10.534844398498535,946132,0.0,0.0
|
||||
2022-04-22 00:00:00+02:00,18.063018798828125,18.25399398803711,17.87204360961914,18.031190872192383,10.385885238647461,876938,0.0,0.0
|
||||
2022-04-25 00:00:00+02:00,17.71687889099121,17.891937255859375,17.549774169921875,17.629348754882812,10.154425621032715,857539,0.0,0.0
|
||||
2022-04-26 00:00:00+02:00,17.868066787719727,17.868066787719727,17.342885971069336,17.342885971069336,9.989424705505371,920938,0.0,0.0
|
||||
2022-04-27 00:00:00+02:00,17.42245864868164,17.513967514038086,16.865449905395508,17.430416107177734,10.039841651916504,995898,0.0,0.0
|
||||
2022-04-28 00:00:00+02:00,17.633325576782227,17.99538230895996,17.601497650146484,17.736770629882812,10.216300964355469,1172803,0.0,0.0
|
||||
2022-04-29 00:00:00+02:00,17.848173141479492,18.10678482055664,17.804407119750977,18.015274047851562,10.376717567443848,988594,0.0,0.0
|
||||
2022-05-02 00:00:00+02:00,17.88397979736328,18.05506134033203,16.90921401977539,17.74074935913086,10.218591690063477,1031151,0.0,0.0
|
||||
2022-05-03 00:00:00+02:00,17.848173141479492,17.93570327758789,17.506010055541992,17.808385848999023,10.257550239562988,1121197,0.0,0.0
|
||||
2022-05-04 00:00:00+02:00,18.747344970703125,19.10542106628418,18.532499313354492,18.846811294555664,10.855679512023926,2131889,0.0,0.0
|
||||
2022-05-05 00:00:00+02:00,19.18101692199707,19.37994956970215,18.138612747192383,18.17840003967285,10.470675468444824,1420586,0.0,0.0
|
||||
2022-05-06 00:00:00+02:00,18.110763549804688,18.560348510742188,17.97150993347168,18.369373321533203,10.580676078796387,967240,0.0,0.0
|
||||
2022-05-09 00:00:00+02:00,18.190336227416992,18.305715560913086,17.844194412231445,17.951616287231445,10.340049743652344,1063615,0.0,0.0
|
||||
2022-05-10 00:00:00+02:00,18.063018798828125,18.85079002380371,18.04710578918457,18.341524124145508,10.56463623046875,1106715,0.0,0.0
|
||||
2022-05-11 00:00:00+02:00,18.46088218688965,18.659814834594727,18.27786636352539,18.47281837463379,10.640260696411133,916544,0.0,0.0
|
||||
2022-05-12 00:00:00+02:00,18.04312515258789,18.261951446533203,17.784513473510742,18.222164154052734,10.495885848999023,899448,0.0,0.0
|
||||
2022-05-13 00:00:00+02:00,18.405181884765625,18.55636978149414,18.194313049316406,18.38528823852539,10.58984375,614260,0.0,0.0
|
||||
2022-05-16 00:00:00+02:00,18.381309509277344,18.612070083618164,18.24205780029297,18.417118072509766,10.60817813873291,734648,0.0,0.0
|
||||
2022-05-17 00:00:00+02:00,18.21420669555664,18.747344970703125,18.21420669555664,18.512605667114258,12.222789764404297,625555,2.35,0.0
|
||||
2022-05-18 00:00:00+02:00,18.54443359375,18.592178344726562,18.357437133789062,18.357437133789062,12.120341300964355,676447,0.0,0.0
|
||||
2022-05-19 00:00:00+02:00,17.677091598510742,17.903873443603516,17.474180221557617,17.513967514038086,11.563446998596191,1239650,0.0,0.0
|
||||
2022-05-20 00:00:00+02:00,17.856130599975586,18.063018798828125,17.60547637939453,17.60547637939453,11.623865127563477,792884,0.0,0.0
|
||||
2022-05-23 00:00:00+02:00,17.85215187072754,17.987424850463867,17.633325576782227,17.987424850463867,11.876043319702148,661658,0.0,0.0
|
||||
2022-05-24 00:00:00+02:00,17.79247283935547,17.83623695373535,17.414501190185547,17.418479919433594,11.500401496887207,729103,0.0,0.0
|
||||
2022-05-25 00:00:00+02:00,17.617412567138672,17.89989471435547,17.394607543945312,17.8402156829834,11.778849601745605,645185,0.0,0.0
|
||||
2022-05-26 00:00:00+02:00,17.79247283935547,18.05506134033203,17.720855712890625,18.03516960144043,11.90756607055664,523872,0.0,0.0
|
||||
2022-05-27 00:00:00+02:00,18.031190872192383,18.198293685913086,17.94763946533203,18.198293685913086,12.015267372131348,578243,0.0,0.0
|
||||
2022-05-30 00:00:00+02:00,18.27786636352539,18.433032989501953,18.10678482055664,18.218185424804688,12.028400421142578,568621,0.0,0.0
|
||||
2022-05-31 00:00:00+02:00,18.1823787689209,18.218185424804688,17.97150993347168,18.122699737548828,11.965357780456543,1795488,0.0,0.0
|
||||
2022-06-01 00:00:00+02:00,18.293779373168945,18.44496726989746,18.17840003967285,18.28980255126953,12.075685501098633,494450,0.0,0.0
|
||||
2022-06-02 00:00:00+02:00,18.3494815826416,18.532499313354492,18.3494815826416,18.4569034576416,12.186012268066406,412331,0.0,0.0
|
||||
2022-06-03 00:00:00+02:00,18.592178344726562,18.639921188354492,18.433032989501953,18.564327239990234,12.256937980651855,487960,0.0,0.0
|
||||
2022-06-06 00:00:00+02:00,18.72745132446289,18.830896377563477,18.56830596923828,18.592178344726562,12.2753267288208,605186,0.0,0.0
|
||||
2022-06-07 00:00:00+02:00,18.500669479370117,18.540456771850586,18.32560920715332,18.468839645385742,12.193892478942871,606368,0.0,0.0
|
||||
2022-06-08 00:00:00+02:00,18.512605667114258,18.616050720214844,18.44496726989746,18.564327239990234,12.256937980651855,631100,0.0,0.0
|
||||
2022-06-09 00:00:00+02:00,18.452926635742188,18.82691764831543,18.401203155517578,18.41313934326172,12.15711784362793,1105870,0.0,0.0
|
||||
2022-06-10 00:00:00+02:00,18.273887634277344,18.31367301940918,17.685047149658203,17.685047149658203,11.676401138305664,933108,0.0,0.0
|
||||
2022-06-13 00:00:00+02:00,17.506010055541992,17.768600463867188,17.223526000976562,17.521923065185547,11.56869888305664,1102884,0.0,0.0
|
||||
2022-06-14 00:00:00+02:00,17.71289825439453,17.756664276123047,17.255355834960938,17.255355834960938,11.3927001953125,815872,0.0,0.0
|
||||
2022-06-15 00:00:00+02:00,17.486116409301758,18.015274047851562,17.42245864868164,17.621389389038086,11.634371757507324,987976,0.0,0.0
|
||||
2022-06-16 00:00:00+02:00,17.533859252929688,17.577625274658203,16.328332901000977,16.328332901000977,10.78064250946045,1421657,0.0,0.0
|
||||
2022-06-17 00:00:00+02:00,16.391990661621094,16.694366455078125,16.06574249267578,16.248760223388672,10.728104591369629,3094063,0.0,0.0
|
||||
2022-06-20 00:00:00+02:00,16.40790557861328,16.427799224853516,16.12542152404785,16.356182098388672,10.799028396606445,496948,0.0,0.0
|
||||
2022-06-21 00:00:00+02:00,16.491456985473633,16.821683883666992,16.427799224853516,16.48349952697754,10.883090019226074,563534,0.0,0.0
|
||||
2022-06-22 00:00:00+02:00,16.208974838256836,16.208974838256836,15.759387016296387,15.819067001342773,10.444403648376465,1050007,0.0,0.0
|
||||
2022-06-23 00:00:00+02:00,15.735515594482422,15.799174308776855,15.285928726196289,15.30980110168457,10.108163833618164,1064414,0.0,0.0
|
||||
2022-06-24 00:00:00+02:00,15.413246154785156,15.898639678955078,15.234207153320312,15.86681079864502,10.475926399230957,1215616,0.0,0.0
|
||||
2022-06-27 00:00:00+02:00,16.01799964904785,16.328332901000977,15.958318710327148,16.117464065551758,10.64141845703125,1182615,0.0,0.0
|
||||
2022-06-28 00:00:00+02:00,16.248760223388672,16.519306182861328,16.045848846435547,16.181123733520508,10.683448791503906,1274280,0.0,0.0
|
||||
2022-06-29 00:00:00+02:00,16.014020919799805,16.06574249267578,15.468947410583496,15.528626441955566,10.252642631530762,1058236,0.0,0.0
|
||||
2022-06-30 00:00:00+02:00,15.234207153320312,15.381417274475098,14.800535202026367,15.381417274475098,10.155447959899902,1934410,0.0,0.0
|
||||
2022-07-01 00:00:00+02:00,15.277972221374512,15.679815292358398,15.230228424072266,15.377437591552734,10.15282154083252,909034,0.0,0.0
|
||||
2022-07-04 00:00:00+02:00,15.564434051513672,15.791215896606445,15.488840103149414,15.687771797180176,10.35771656036377,798569,0.0,0.0
|
||||
2022-07-05 00:00:00+02:00,15.763365745544434,15.91455364227295,14.884086608886719,14.884086608886719,9.8270902633667,1966763,0.0,0.0
|
||||
2022-07-06 00:00:00+02:00,15.079039573669434,15.202378273010254,14.907958984375,15.110869407653809,9.976822853088379,938909,0.0,0.0
|
||||
2022-07-07 00:00:00+02:00,15.301843643188477,15.898639678955078,15.23818588256836,15.807130813598633,10.436522483825684,1170179,0.0,0.0
|
||||
2022-07-08 00:00:00+02:00,15.69572925567627,16.39596939086914,15.532605171203613,16.049827575683594,10.596760749816895,1372047,0.0,0.0
|
||||
2022-07-11 00:00:00+02:00,15.608199119567871,15.69572925567627,15.285928726196289,15.488840103149414,10.226373672485352,877119,0.0,0.0
|
||||
2022-07-12 00:00:00+02:00,15.381417274475098,15.556476593017578,14.983552932739258,15.520668983459473,10.24738883972168,1161955,0.0,0.0
|
||||
2022-07-13 00:00:00+02:00,15.425182342529297,15.647985458374023,15.234207153320312,15.357544898986816,10.139686584472656,1081802,0.0,0.0
|
||||
2022-07-14 00:00:00+02:00,15.333672523498535,15.357544898986816,14.728919982910156,14.888065338134766,9.829717636108398,896311,0.0,0.0
|
||||
2022-07-15 00:00:00+02:00,14.959680557250977,15.548519134521484,14.923872947692871,15.433138847351074,10.189598083496094,1160019,0.0,0.0
|
||||
2022-07-18 00:00:00+02:00,15.970254898071289,16.316396713256836,15.894660949707031,16.133378982543945,10.651925086975098,1770123,0.0,0.0
|
||||
2022-07-19 00:00:00+02:00,16.010042190551758,16.698345184326172,15.755409240722656,16.48349952697754,10.883090019226074,1574206,0.0,0.0
|
||||
2022-07-20 00:00:00+02:00,16.551136016845703,16.67845344543457,16.145315170288086,16.439735412597656,10.854194641113281,876721,0.0,0.0
|
||||
2022-07-21 00:00:00+02:00,16.30048179626465,16.646623611450195,16.16520881652832,16.364139556884766,10.804283142089844,1014598,0.0,0.0
|
||||
2022-07-22 00:00:00+02:00,16.244781494140625,16.463605880737305,15.98219108581543,16.037891387939453,10.58888053894043,1100753,0.0,0.0
|
||||
2022-07-25 00:00:00+02:00,16.014020919799805,16.39596939086914,15.874768257141113,16.11348533630371,10.638790130615234,826151,0.0,0.0
|
||||
2022-07-26 00:00:00+02:00,16.11348533630371,16.133378982543945,15.600241661071777,15.715621948242188,10.376105308532715,1071673,0.0,0.0
|
||||
2022-07-27 00:00:00+02:00,15.894660949707031,15.970254898071289,15.703685760498047,15.950362205505371,10.531089782714844,1076946,0.0,0.0
|
||||
2022-07-28 00:00:00+02:00,16.368118286132812,16.686410903930664,16.232845306396484,16.551136016845703,10.927746772766113,1713701,0.0,0.0
|
||||
2022-07-29 00:00:00+02:00,16.634687423706055,17.084274291992188,16.551136016845703,17.00868034362793,11.229835510253906,1096515,0.0,0.0
|
||||
2022-08-01 00:00:00+02:00,17.088253021240234,17.303098678588867,16.83759880065918,16.861469268798828,11.132641792297363,698449,0.0,0.0
|
||||
2022-08-02 00:00:00+02:00,16.833620071411133,16.992765426635742,16.674474716186523,16.937063217163086,11.182550430297852,683927,0.0,0.0
|
||||
2022-08-03 00:00:00+02:00,16.92115020751953,17.175783157348633,16.83759880065918,17.12008285522461,11.303388595581055,520776,0.0,0.0
|
||||
2022-08-04 00:00:00+02:00,17.132017135620117,17.334928512573242,17.004701614379883,17.064380645751953,11.266611099243164,770841,0.0,0.0
|
||||
2022-08-05 00:00:00+02:00,17.100189208984375,17.283206939697266,16.821683883666992,17.104167938232422,11.292880058288574,676884,0.0,0.0
|
||||
2022-08-08 00:00:00+02:00,17.283206939697266,17.47020149230957,17.076316833496094,17.319013595581055,11.434730529785156,640299,0.0,0.0
|
||||
2022-08-09 00:00:00+02:00,17.247398376464844,17.342885971069336,16.9808292388916,17.112125396728516,11.298134803771973,513653,0.0,0.0
|
||||
2022-08-10 00:00:00+02:00,17.084274291992188,17.43439483642578,16.90921401977539,17.394607543945312,11.484639167785645,565334,0.0,0.0
|
||||
2022-08-11 00:00:00+02:00,17.45826530456543,17.474180221557617,17.15191078186035,17.267290115356445,11.400580406188965,740132,0.0,0.0
|
||||
2022-08-12 00:00:00+02:00,17.23944091796875,17.486116409301758,17.231483459472656,17.342885971069336,11.450491905212402,966868,0.0,0.0
|
||||
2022-08-15 00:00:00+02:00,17.346864700317383,17.474180221557617,17.064380645751953,17.243419647216797,11.384819984436035,404314,0.0,0.0
|
||||
2022-08-16 00:00:00+02:00,17.342885971069336,17.426437377929688,17.175783157348633,17.36277961730957,11.46362590789795,615567,0.0,0.0
|
||||
2022-08-17 00:00:00+02:00,17.44632911682129,17.525903701782227,16.742111206054688,16.76598358154297,11.069597244262695,1020374,0.0,0.0
|
||||
2022-08-18 00:00:00+02:00,16.821683883666992,17.25137710571289,16.769962310791016,16.853513717651367,11.127388000488281,738694,0.0,0.0
|
||||
2022-08-19 00:00:00+02:00,16.69038963317871,16.901256561279297,16.606836318969727,16.606836318969727,10.964521408081055,628184,0.0,0.0
|
||||
2022-08-22 00:00:00+02:00,16.479520797729492,16.527265548706055,15.92251205444336,15.978212356567383,10.549478530883789,866276,0.0,0.0
|
||||
2022-08-23 00:00:00+02:00,15.942404747009277,16.292524337768555,15.918533325195312,16.292524337768555,10.756999015808105,860233,0.0,0.0
|
||||
2022-08-24 00:00:00+02:00,16.268653869628906,16.308439254760742,15.950362205505371,16.240802764892578,10.72284984588623,704240,0.0,0.0
|
||||
2022-08-25 00:00:00+02:00,16.388011932373047,16.523286819458008,16.216930389404297,16.292524337768555,10.756999015808105,479490,0.0,0.0
|
||||
2022-08-26 00:00:00+02:00,16.439735412597656,16.598880767822266,15.958318710327148,15.990147590637207,10.557356834411621,546820,0.0,0.0
|
||||
2022-08-29 00:00:00+02:00,15.91455364227295,16.44769287109375,15.743473052978516,16.43177604675293,10.84893798828125,771344,0.0,0.0
|
||||
2022-08-30 00:00:00+02:00,16.54317855834961,16.67845344543457,16.15327262878418,16.248760223388672,10.728104591369629,741509,0.0,0.0
|
||||
2022-08-31 00:00:00+02:00,16.356182098388672,16.44371223449707,16.0418701171875,16.0418701171875,10.591507911682129,956161,0.0,0.0
|
||||
2022-09-01 00:00:00+02:00,15.978212356567383,15.978212356567383,15.691749572753906,15.755409240722656,10.402374267578125,998562,0.0,0.0
|
||||
2022-09-02 00:00:00+02:00,16.161230087280273,16.519306182861328,15.962298393249512,16.391990661621094,10.822671890258789,997552,0.0,0.0
|
||||
2022-09-05 00:00:00+02:00,15.874768257141113,15.91455364227295,15.520668983459473,15.723580360412598,10.381360054016113,1129909,0.0,0.0
|
||||
2022-09-06 00:00:00+02:00,15.763365745544434,16.09359359741211,15.683793067932129,15.86681079864502,10.475926399230957,638791,0.0,0.0
|
||||
2022-09-07 00:00:00+02:00,15.616155624389648,16.264673233032227,15.58034896850586,16.21295166015625,10.704462051391602,819365,0.0,0.0
|
||||
2022-09-08 00:00:00+02:00,16.292524337768555,16.364139556884766,15.954340934753418,16.14133644104004,10.65717887878418,690130,0.0,0.0
|
||||
2022-09-09 00:00:00+02:00,16.19305992126465,16.575008392333984,16.19305992126465,16.427799224853516,10.8463134765625,623223,0.0,0.0
|
||||
2022-09-12 00:00:00+02:00,16.614795684814453,17.076316833496094,16.571029663085938,16.98480796813965,11.21407413482666,880959,0.0,0.0
|
||||
2022-09-13 00:00:00+02:00,17.02061653137207,17.549774169921875,16.698345184326172,16.722217559814453,11.04069995880127,1949078,0.0,0.0
|
||||
2022-09-14 00:00:00+02:00,16.55511474609375,16.65458106994629,16.06574249267578,16.316396713256836,10.772761344909668,1147799,0.0,0.0
|
||||
2022-09-15 00:00:00+02:00,16.316396713256836,16.50737190246582,16.01799964904785,16.12542152404785,10.646671295166016,704698,0.0,0.0
|
||||
2022-09-16 00:00:00+02:00,15.92648983001709,16.05380630493164,15.647985458374023,15.954340934753418,10.533716201782227,1934284,0.0,0.0
|
||||
2022-09-19 00:00:00+02:00,15.890682220458984,16.419841766357422,15.791215896606445,16.368118286132812,10.806910514831543,961766,0.0,0.0
|
||||
2022-09-20 00:00:00+02:00,16.44769287109375,16.55511474609375,15.930468559265137,15.99412727355957,10.559986114501953,712846,0.0,0.0
|
||||
2022-09-21 00:00:00+02:00,15.894660949707031,16.137357711791992,15.815088272094727,16.1294002532959,10.649297714233398,557165,0.0,0.0
|
||||
2022-09-22 00:00:00+02:00,15.727558135986328,16.197038650512695,15.667879104614258,16.069721221923828,10.609895706176758,892616,0.0,0.0
|
||||
2022-09-23 00:00:00+02:00,16.0418701171875,16.161230087280273,15.64002799987793,15.854874610900879,10.468045234680176,1425407,0.0,0.0
|
||||
2022-09-26 00:00:00+02:00,15.675835609436035,16.037891387939453,15.604220390319824,15.604220390319824,10.302553176879883,823367,0.0,0.0
|
||||
2022-09-27 00:00:00+02:00,15.6360502243042,15.886704444885254,15.492818832397461,15.687771797180176,10.35771656036377,1239006,0.0,0.0
|
||||
2022-09-28 00:00:00+02:00,15.433138847351074,16.109508514404297,15.170549392700195,15.990147590637207,10.557356834411621,1753368,0.0,0.0
|
||||
2022-09-29 00:00:00+02:00,15.986169815063477,15.986169815063477,15.40926742553711,15.516690254211426,10.24476146697998,1373640,0.0,0.0
|
||||
2022-09-30 00:00:00+02:00,15.6360502243042,15.894660949707031,15.528626441955566,15.842939376831055,10.460165023803711,1225082,0.0,0.0
|
||||
2022-10-03 00:00:00+02:00,15.671856880187988,16.419841766357422,15.628091812133789,16.34822654724121,10.793776512145996,968647,0.0,0.0
|
||||
2022-10-04 00:00:00+02:00,16.618772506713867,17.267290115356445,16.618772506713867,17.267290115356445,11.400580406188965,1425231,0.0,0.0
|
||||
2022-10-05 00:00:00+02:00,17.100189208984375,17.35084342956543,17.016637802124023,17.08029556274414,11.277118682861328,1216119,0.0,0.0
|
||||
2022-10-06 00:00:00+02:00,17.203632354736328,17.32697105407715,16.88534164428711,16.976850509643555,11.208819389343262,825166,0.0,0.0
|
||||
2022-10-07 00:00:00+02:00,16.976850509643555,17.12803840637207,16.65458106994629,16.730175018310547,11.045954704284668,839674,0.0,0.0
|
||||
2022-10-10 00:00:00+02:00,16.610815048217773,17.56966781616211,16.586944580078125,17.402565002441406,11.489893913269043,1029281,0.0,0.0
|
||||
2022-10-11 00:00:00+02:00,17.088253021240234,17.23944091796875,16.284568786621094,16.463605880737305,10.869954109191895,2020228,0.0,0.0
|
||||
2022-10-12 00:00:00+02:00,16.499414443969727,16.929107666015625,16.320375442504883,16.789854049682617,11.085356712341309,1510536,0.0,0.0
|
||||
2022-10-13 00:00:00+02:00,16.694366455078125,17.17976188659668,16.384033203125,17.17976188659668,11.342791557312012,1551570,0.0,0.0
|
||||
2022-10-14 00:00:00+02:00,17.525903701782227,17.69300651550293,16.841577529907227,17.012659072875977,11.232461929321289,1388605,0.0,0.0
|
||||
2022-10-17 00:00:00+02:00,17.012659072875977,17.49407386779785,16.913192749023438,17.287185668945312,11.413715362548828,857670,0.0,0.0
|
||||
2022-10-18 00:00:00+02:00,17.43439483642578,17.951616287231445,17.39858627319336,17.617412567138672,11.631746292114258,1118895,0.0,0.0
|
||||
2022-10-19 00:00:00+02:00,17.732791900634766,17.820322036743164,17.565689086914062,17.58160400390625,11.60810375213623,659672,0.0,0.0
|
||||
2022-10-20 00:00:00+02:00,17.4980525970459,17.796449661254883,17.414501190185547,17.677091598510742,11.671148300170898,869126,0.0,0.0
|
||||
2022-10-21 00:00:00+02:00,17.506010055541992,17.85215187072754,17.346864700317383,17.85215187072754,11.786728858947754,781749,0.0,0.0
|
||||
2022-10-24 00:00:00+02:00,18.699600219726562,18.834875106811523,17.708919525146484,18.345502853393555,12.11246109008789,1695268,0.0,0.0
|
||||
2022-10-25 00:00:00+02:00,18.440990447998047,18.627986907958984,17.931724548339844,18.202272415161133,12.017894744873047,1131150,0.0,0.0
|
||||
2022-10-26 00:00:00+02:00,18.22614288330078,18.43701171875,17.975488662719727,18.329587936401367,12.10195255279541,1222905,0.0,0.0
|
||||
2022-10-27 00:00:00+02:00,18.341524124145508,18.600135803222656,18.08291244506836,18.293779373168945,12.078311920166016,778065,0.0,0.0
|
||||
2022-10-28 00:00:00+02:00,18.078933715820312,18.32560920715332,17.975488662719727,18.269908905029297,12.06255054473877,1099727,0.0,0.0
|
||||
2022-10-31 00:00:00+01:00,18.369373321533203,18.532499313354492,18.14259147644043,18.150548934936523,11.983743667602539,1018936,0.0,0.0
|
||||
2022-11-01 00:00:00+01:00,18.293779373168945,18.492712020874023,18.063018798828125,18.15452766418457,11.986371040344238,1016061,0.0,0.0
|
||||
2022-11-02 00:00:00+01:00,18.186357498168945,18.194313049316406,17.88397979736328,18.063018798828125,11.925954818725586,1299861,0.0,0.0
|
||||
2022-11-03 00:00:00+01:00,17.69300651550293,18.015274047851562,17.406543731689453,17.98344612121582,11.873414993286133,1179101,0.0,0.0
|
||||
2022-11-04 00:00:00+01:00,18.202272415161133,18.894554138183594,18.15452766418457,18.791109085083008,12.406668663024902,1369272,0.0,0.0
|
||||
2022-11-07 00:00:00+01:00,18.759281158447266,19.391883850097656,18.659814834594727,19.336183547973633,12.766550064086914,1259541,0.0,0.0
|
||||
2022-11-08 00:00:00+01:00,19.332204818725586,19.566944122314453,19.188974380493164,19.41177749633789,12.816459655761719,886906,0.0,0.0
|
||||
2022-11-09 00:00:00+01:00,19.415756225585938,19.415756225585938,18.954233169555664,19.208866119384766,12.682489395141602,1198007,0.0,0.0
|
||||
2022-11-10 00:00:00+01:00,19.153165817260742,19.59479522705078,19.03778648376465,19.586837768554688,12.93204116821289,1410472,0.0,0.0
|
||||
2022-11-11 00:00:00+01:00,19.59479522705078,19.857385635375977,19.562965393066406,19.78974723815918,13.066010475158691,1274687,0.0,0.0
|
||||
2022-11-14 00:00:00+01:00,19.81361961364746,20.112018585205078,19.690282821655273,20.032445907592773,13.226252555847168,1295287,0.0,0.0
|
||||
2022-11-15 00:00:00+01:00,20.01255226135254,20.191591262817383,19.61071014404297,19.805662155151367,13.076519966125488,1056914,0.0,0.0
|
||||
2022-11-16 00:00:00+01:00,19.75394058227539,19.785770416259766,19.276504516601562,19.44758415222168,12.840100288391113,1015000,0.0,0.0
|
||||
2022-11-17 00:00:00+01:00,19.4833927154541,19.65447425842285,19.09746551513672,19.296396255493164,12.740280151367188,644501,0.0,0.0
|
||||
2022-11-18 00:00:00+01:00,19.42371368408203,19.666410446166992,19.332204818725586,19.666410446166992,12.984579086303711,829590,0.0,0.0
|
||||
2022-11-21 00:00:00+01:00,19.598773956298828,19.606731414794922,19.02187156677246,19.101444244384766,12.611564636230469,918183,0.0,0.0
|
||||
2022-11-22 00:00:00+01:00,19.137252807617188,19.49930763244629,19.073593139648438,19.395862579345703,12.805953025817871,915438,0.0,0.0
|
||||
2022-11-23 00:00:00+01:00,19.475435256958008,19.51124382019043,19.149187088012695,19.264568328857422,12.719265937805176,867427,0.0,0.0
|
||||
2022-11-24 00:00:00+01:00,19.31231117248535,19.551029205322266,19.31231117248535,19.539094924926758,12.900519371032715,658838,0.0,0.0
|
||||
2022-11-25 00:00:00+01:00,19.535114288330078,19.574901580810547,19.371990203857422,19.419734954833984,12.8217134475708,444192,0.0,0.0
|
||||
2022-11-28 00:00:00+01:00,19.296396255493164,19.356077194213867,19.085529327392578,19.16908073425293,12.656221389770508,743198,0.0,0.0
|
||||
2022-11-29 00:00:00+01:00,18.830896377563477,18.978105545043945,18.572284698486328,18.72745132446289,12.364640235900879,1801344,0.0,0.0
|
||||
2022-11-30 00:00:00+01:00,18.89853286743164,18.92638397216797,18.405181884765625,18.675729751586914,12.330490112304688,1555300,0.0,0.0
|
||||
2022-12-01 00:00:00+01:00,18.87466049194336,18.958213806152344,18.56830596923828,18.73938751220703,12.372520446777344,1102744,0.0,0.0
|
||||
2022-12-02 00:00:00+01:00,18.663793563842773,19.013914108276367,18.55636978149414,19.005956649780273,12.5485200881958,783142,0.0,0.0
|
||||
2022-12-05 00:00:00+01:00,18.966169357299805,19.061656951904297,18.73938751220703,18.86272621154785,12.453953742980957,726414,0.0,0.0
|
||||
2022-12-06 00:00:00+01:00,18.870683670043945,19.073593139648438,18.791109085083008,18.962190628051758,12.519624710083008,752418,0.0,0.0
|
||||
2022-12-07 00:00:00+01:00,18.922405242919922,18.958213806152344,18.572284698486328,18.62002944946289,12.293715476989746,1312303,0.0,0.0
|
||||
2022-12-08 00:00:00+01:00,18.48475456237793,18.759281158447266,18.421096801757812,18.516584396362305,12.225415229797363,1077991,0.0,0.0
|
||||
2022-12-09 00:00:00+01:00,18.56830596923828,18.890575408935547,18.52056312561035,18.83885383605957,12.438191413879395,876148,0.0,0.0
|
||||
2022-12-12 00:00:00+01:00,18.735408782958984,18.763259887695312,18.417118072509766,18.468839645385742,12.193892478942871,1151398,0.0,0.0
|
||||
2022-12-13 00:00:00+01:00,18.604114532470703,19.065635681152344,18.552391052246094,18.942298889160156,12.506489753723145,1226494,0.0,0.0
|
||||
2022-12-14 00:00:00+01:00,18.858747482299805,19.017892837524414,18.75530242919922,18.8865966796875,12.469715118408203,958418,0.0,0.0
|
||||
2022-12-15 00:00:00+01:00,18.73938751220703,18.751323699951172,18.369373321533203,18.47281837463379,12.19651985168457,1115743,0.0,0.0
|
||||
2022-12-16 00:00:00+01:00,18.4569034576416,18.627986907958984,18.329587936401367,18.564327239990234,12.256937980651855,1941860,0.0,0.0
|
||||
2022-12-19 00:00:00+01:00,18.58422088623047,18.75530242919922,18.548412322998047,18.627986907958984,12.298968315124512,778150,0.0,0.0
|
||||
2022-12-20 00:00:00+01:00,18.504648208618164,18.7990665435791,18.393245697021484,18.7990665435791,12.411921501159668,935164,0.0,0.0
|
||||
2022-12-21 00:00:00+01:00,18.89853286743164,19.244674682617188,18.8865966796875,19.208866119384766,12.682489395141602,1124419,0.0,0.0
|
||||
2022-12-22 00:00:00+01:00,19.272525787353516,19.38790512084961,18.783153533935547,18.82691764831543,12.430309295654297,1217165,0.0,0.0
|
||||
2022-12-23 00:00:00+01:00,18.89853286743164,19.14520835876465,18.81498146057129,19.0338077545166,12.566908836364746,552525,0.0,0.0
|
||||
2022-12-27 00:00:00+01:00,19.177038192749023,19.24069595336914,19.03778648376465,19.04972267150879,12.57741641998291,387951,0.0,0.0
|
||||
2022-12-28 00:00:00+01:00,19.09746551513672,19.177038192749023,18.934341430664062,19.005956649780273,12.5485200881958,517744,0.0,0.0
|
||||
2022-12-29 00:00:00+01:00,19.001977920532227,19.077571868896484,18.8865966796875,19.045743942260742,12.574789047241211,398794,0.0,0.0
|
||||
2022-12-30 00:00:00+01:00,18.946277618408203,19.017892837524414,18.75530242919922,18.791109085083008,12.406668663024902,449339,0.0,0.0
|
||||
2023-01-02 00:00:00+01:00,18.990041732788086,19.383926391601562,18.914447784423828,19.383926391601562,12.798072814941406,671340,0.0,0.0
|
||||
2023-01-03 00:00:00+01:00,19.356077194213867,19.78179168701172,19.344141006469727,19.435649871826172,12.832221984863281,983215,0.0,0.0
|
||||
2023-01-04 00:00:00+01:00,19.48737144470215,19.982711791992188,19.44758415222168,19.94292640686035,13.167146682739258,1333355,0.0,0.0
|
||||
2023-01-05 00:00:00+01:00,19.932979583740234,20.121965408325195,19.845449447631836,20.002605438232422,13.206549644470215,1261924,0.0,0.0
|
||||
2023-01-06 00:00:00+01:00,20.112018585205078,20.410415649414062,19.95287322998047,20.410415649414062,13.47580337524414,641716,0.0,0.0
|
||||
2023-01-09 00:00:00+01:00,20.410415649414062,20.569562911987305,20.32089614868164,20.440256118774414,13.495504379272461,839910,0.0,0.0
|
||||
2023-01-10 00:00:00+01:00,20.48004150390625,20.48004150390625,19.932979583740234,20.17169761657715,13.31818962097168,1099813,0.0,0.0
|
||||
2023-01-11 00:00:00+01:00,20.241323471069336,20.838119506835938,20.10207176208496,20.599401473999023,13.600579261779785,1479852,0.0,0.0
|
||||
2023-01-12 00:00:00+01:00,20.60934829711914,20.758546829223633,20.470096588134766,20.639188766479492,13.626847267150879,1067892,0.0,0.0
|
||||
2023-01-13 00:00:00+01:00,20.559614181518555,21.01715850830078,20.430309295654297,20.788387298583984,13.72535514831543,1563851,0.0,0.0
|
||||
2023-01-16 00:00:00+01:00,20.589454650878906,20.72870635986328,20.181644439697266,20.70881462097168,14.766735076904297,790612,1.54,0.0
|
||||
2023-01-17 00:00:00+01:00,20.698867797851562,20.997264862060547,20.499935150146484,20.659080505371094,14.731270790100098,917298,0.0,0.0
|
||||
2023-01-18 00:00:00+01:00,20.649133682250977,20.80828094482422,20.39052391052246,20.688920974731445,14.752549171447754,976454,0.0,0.0
|
||||
2023-01-19 00:00:00+01:00,20.569562911987305,20.57950782775879,20.26121711730957,20.39052391052246,14.539773941040039,888012,0.0,0.0
|
||||
2023-01-20 00:00:00+01:00,20.529775619506836,20.649133682250977,20.340789794921875,20.619295120239258,14.702900886535645,757103,0.0,0.0
|
||||
2023-01-23 00:00:00+01:00,20.678974151611328,20.70881462097168,20.5098819732666,20.57950782775879,14.674530029296875,540245,0.0,0.0
|
||||
2023-01-24 00:00:00+01:00,20.688920974731445,20.72870635986328,20.599401473999023,20.72870635986328,14.780917167663574,497230,0.0,0.0
|
||||
2023-01-25 00:00:00+01:00,20.72870635986328,20.788387298583984,20.539722442626953,20.72870635986328,14.780917167663574,610198,0.0,0.0
|
||||
2023-01-26 00:00:00+01:00,20.82817268371582,21.01715850830078,20.549667358398438,21.01715850830078,14.986603736877441,1177819,0.0,0.0
|
||||
2023-01-27 00:00:00+01:00,21.0271053314209,21.315555572509766,20.937585830688477,21.196197509765625,15.11427116394043,1399061,0.0,0.0
|
||||
2023-01-30 00:00:00+01:00,21.106678009033203,21.196197509765625,20.967424392700195,21.096731185913086,15.043343544006348,1048142,0.0,0.0
|
||||
2023-01-31 00:00:00+01:00,21.156410217285156,21.255876541137695,21.007211685180664,21.216089248657227,15.128454208374023,1153987,0.0,0.0
|
||||
2023-02-01 00:00:00+01:00,21.36528968811035,21.633846282958984,21.295663833618164,21.604007720947266,15.40506649017334,1127903,0.0,0.0
|
||||
2023-02-02 00:00:00+01:00,21.604007720947266,21.922298431396484,21.514488220214844,21.792993545532227,15.539824485778809,1405008,0.0,0.0
|
||||
2023-02-03 00:00:00+01:00,21.733312606811523,21.981977462768555,21.6437931060791,21.981977462768555,15.674581527709961,1224408,0.0,0.0
|
||||
2023-02-06 00:00:00+01:00,21.713420867919922,21.862619400024414,21.514488220214844,21.6437931060791,15.43343448638916,1078283,0.0,0.0
|
||||
2023-02-07 00:00:00+01:00,21.812885284423828,21.912351608276367,21.6437931060791,21.65374183654785,15.440529823303223,983431,0.0,0.0
|
||||
2023-02-08 00:00:00+01:00,21.68358039855957,22.051603317260742,21.68358039855957,21.832778930664062,15.568195343017578,983919,0.0,0.0
|
||||
2023-02-09 00:00:00+01:00,21.862619400024414,22.03171157836914,21.74325942993164,21.892459869384766,15.610750198364258,921355,0.0,0.0
|
||||
2023-02-10 00:00:00+01:00,21.773099899291992,21.892459869384766,21.39512825012207,21.58411407470703,15.390880584716797,931770,0.0,0.0
|
||||
2023-02-13 00:00:00+01:00,21.613954544067383,21.68358039855957,21.484647750854492,21.534381866455078,15.355417251586914,653816,0.0,0.0
|
||||
2023-02-14 00:00:00+01:00,21.564220428466797,21.6437931060791,21.415021896362305,21.484647750854492,15.319952964782715,566610,0.0,0.0
|
||||
2023-02-15 00:00:00+01:00,21.385181427001953,21.72336769104004,21.345396041870117,21.703474044799805,15.475992202758789,971141,0.0,0.0
|
||||
2023-02-16 00:00:00+01:00,21.733312606811523,21.852672576904297,21.58411407470703,21.753206253051758,15.511454582214355,860626,0.0,0.0
|
||||
2023-02-17 00:00:00+01:00,21.604007720947266,21.822832107543945,21.484647750854492,21.763153076171875,15.518546104431152,558814,0.0,0.0
|
||||
2023-02-20 00:00:00+01:00,21.78304672241211,22.340055465698242,21.78304672241211,22.340055465698242,15.929916381835938,997833,0.0,0.0
|
||||
2023-02-21 00:00:00+01:00,22.300268173217773,22.4693603515625,22.111284255981445,22.19085693359375,15.823527336120605,907456,0.0,0.0
|
||||
2023-02-22 00:00:00+01:00,21.59406089782715,22.011817932128906,21.484647750854492,21.97203254699707,15.66749095916748,1114536,0.0,0.0
|
||||
2023-02-23 00:00:00+01:00,22.06155014038086,22.06155014038086,21.05694580078125,21.126571655273438,15.064623832702637,2085708,0.0,0.0
|
||||
2023-02-24 00:00:00+01:00,21.126571655273438,21.763153076171875,20.967424392700195,21.07683753967285,15.029159545898438,1493284,0.0,0.0
|
||||
2023-02-27 00:00:00+01:00,21.285715103149414,21.604007720947266,21.206144332885742,21.454809188842773,15.298676490783691,744495,0.0,0.0
|
||||
2023-02-28 00:00:00+01:00,21.325502395629883,21.72336769104004,21.265823364257812,21.534381866455078,15.355417251586914,1797489,0.0,0.0
|
||||
2023-03-01 00:00:00+01:00,21.613954544067383,21.663686752319336,21.30561065673828,21.37523651123047,15.241935729980469,1095414,0.0,0.0
|
||||
2023-03-02 00:00:00+01:00,21.295663833618164,21.43491554260254,21.096731185913086,21.355342864990234,15.227750778198242,729153,0.0,0.0
|
||||
2023-03-03 00:00:00+01:00,21.454809188842773,21.673633575439453,21.444862365722656,21.59406089782715,15.39797306060791,731340,0.0,0.0
|
||||
2023-03-06 00:00:00+01:00,21.59406089782715,21.633846282958984,21.136518478393555,21.136518478393555,15.071715354919434,1177638,0.0,0.0
|
||||
2023-03-07 00:00:00+01:00,21.14646339416504,21.255876541137695,21.0469970703125,21.126571655273438,15.064623832702637,894823,0.0,0.0
|
||||
2023-03-08 00:00:00+01:00,21.0271053314209,21.216089248657227,20.7386531829834,21.216089248657227,15.128454208374023,1145240,0.0,0.0
|
||||
2023-03-09 00:00:00+01:00,21.07683753967285,21.196197509765625,21.01715850830078,21.066890716552734,15.022066116333008,611676,0.0,0.0
|
||||
2023-03-10 00:00:00+01:00,20.76849365234375,21.007211685180664,20.589454650878906,20.897798538208008,14.901491165161133,1111284,0.0,0.0
|
||||
2023-03-13 00:00:00+01:00,20.688920974731445,20.778440475463867,20.07223129272461,20.221431732177734,14.419198036193848,1243550,0.0,0.0
|
||||
2023-03-14 00:00:00+01:00,20.181644439697266,20.470096588134766,19.903139114379883,20.400468826293945,14.546865463256836,1301756,0.0,0.0
|
||||
2023-03-15 00:00:00+01:00,20.430309295654297,20.440256118774414,19.093486785888672,19.121337890625,13.634759902954102,2538134,0.0,0.0
|
||||
2023-03-16 00:00:00+01:00,19.578880310058594,19.68232536315918,18.914447784423828,19.344141006469727,13.793633460998535,1772646,0.0,0.0
|
||||
2023-03-17 00:00:00+01:00,19.395862579345703,19.68232536315918,18.87466049194336,19.20488739013672,13.694336891174316,2459464,0.0,0.0
|
||||
2023-03-20 00:00:00+01:00,19.196931838989258,19.531137466430664,18.723472595214844,19.467479705810547,13.881580352783203,903163,0.0,0.0
|
||||
2023-03-21 00:00:00+01:00,19.73006820678711,20.17169761657715,19.646516799926758,19.972766876220703,14.241883277893066,1270092,0.0,0.0
|
||||
2023-03-22 00:00:00+01:00,19.932979583740234,20.340789794921875,19.869321823120117,20.032445907592773,14.284439086914062,1100120,0.0,0.0
|
||||
2023-03-23 00:00:00+01:00,19.962818145751953,19.962818145751953,19.6584529876709,19.845449447631836,14.151098251342773,1594495,0.0,0.0
|
||||
2023-03-24 00:00:00+01:00,19.74200439453125,19.761898040771484,19.165102005004883,19.726089477539062,14.065988540649414,2008460,0.0,0.0
|
||||
2023-03-27 00:00:00+02:00,20.07223129272461,20.301002502441406,19.833513259887695,20.221431732177734,14.419198036193848,1382281,0.0,0.0
|
||||
2023-03-28 00:00:00+02:00,20.42036247253418,20.559614181518555,20.13191032409668,20.470096588134766,14.596513748168945,1220512,0.0,0.0
|
||||
2023-03-29 00:00:00+02:00,20.559614181518555,20.639188766479492,20.370630264282227,20.539722442626953,14.646161079406738,791707,0.0,0.0
|
||||
2023-03-30 00:00:00+02:00,20.659080505371094,21.01715850830078,20.629241943359375,20.82817268371582,14.851842880249023,968974,0.0,0.0
|
||||
2023-03-31 00:00:00+02:00,20.82817268371582,21.01715850830078,20.748600006103516,20.95747947692871,14.944049835205078,1172265,0.0,0.0
|
||||
2023-04-03 00:00:00+02:00,20.967424392700195,21.066890716552734,20.688920974731445,20.937585830688477,14.929863929748535,1141103,0.0,0.0
|
||||
2023-04-04 00:00:00+02:00,21.08678436279297,21.186250686645508,20.858013153076172,20.858013153076172,14.873122215270996,728163,0.0,0.0
|
||||
2023-04-05 00:00:00+02:00,20.897798538208008,20.947532653808594,20.46014976501465,20.499935150146484,14.617789268493652,1310588,0.0,0.0
|
||||
2023-04-06 00:00:00+02:00,20.649133682250977,20.758546829223633,20.470096588134766,20.589454650878906,14.681623458862305,957116,0.0,0.0
|
||||
2023-04-11 00:00:00+02:00,20.887853622436523,21.216089248657227,20.867958068847656,21.196197509765625,15.11427116394043,1155390,0.0,0.0
|
||||
2023-04-12 00:00:00+02:00,21.156410217285156,21.285715103149414,20.907745361328125,21.226036071777344,15.135547637939453,907456,0.0,0.0
|
||||
2023-04-13 00:00:00+02:00,21.186250686645508,21.385181427001953,21.14646339416504,21.255876541137695,15.156824111938477,1096832,0.0,0.0
|
||||
2023-04-14 00:00:00+02:00,21.315555572509766,21.514488220214844,21.216089248657227,21.484647750854492,15.319952964782715,1071929,0.0,0.0
|
||||
2023-04-17 00:00:00+02:00,21.882511138916016,22.07149887084961,21.58411407470703,21.892459869384766,15.610750198364258,1508490,0.0,0.0
|
||||
2023-04-18 00:00:00+02:00,21.862619400024414,22.041658401489258,21.484647750854492,21.613954544067383,15.41215991973877,1127797,0.0,0.0
|
||||
2023-04-19 00:00:00+02:00,21.633846282958984,21.65374183654785,21.37523651123047,21.633846282958984,15.426342964172363,908843,0.0,0.0
|
||||
2023-04-20 00:00:00+02:00,21.68358039855957,21.68358039855957,21.484647750854492,21.6239013671875,15.41925048828125,810257,0.0,0.0
|
||||
2023-04-21 00:00:00+02:00,21.58411407470703,21.58411407470703,21.255876541137695,21.424968719482422,15.277397155761719,823291,0.0,0.0
|
||||
2023-04-24 00:00:00+02:00,21.385181427001953,21.703474044799805,21.295663833618164,21.633846282958984,15.426342964172363,882673,0.0,0.0
|
||||
2023-04-25 00:00:00+02:00,21.59406089782715,21.74325942993164,21.385181427001953,21.663686752319336,15.447622299194336,1318878,0.0,0.0
|
||||
2023-04-26 00:00:00+02:00,21.464754104614258,21.613954544067383,21.096731185913086,21.613954544067383,15.41215991973877,1135730,0.0,0.0
|
||||
2023-04-27 00:00:00+02:00,21.504541397094727,21.504541397094727,20.897798538208008,21.11662483215332,15.05752944946289,1167454,0.0,0.0
|
||||
2023-04-28 00:00:00+02:00,21.136518478393555,21.65374183654785,21.007211685180664,21.65374183654785,15.440529823303223,1480858,0.0,0.0
|
||||
2023-05-02 00:00:00+02:00,21.68358039855957,21.713420867919922,21.126571655273438,21.14646339416504,15.078805923461914,1146537,0.0,0.0
|
||||
2023-05-03 00:00:00+02:00,21.285715103149414,21.504541397094727,21.186250686645508,21.424968719482422,15.277397155761719,1054129,0.0,0.0
|
||||
2023-05-04 00:00:00+02:00,20.987319946289062,21.6437931060791,20.340789794921875,20.66902732849121,14.738363265991211,1741640,0.0,0.0
|
||||
2023-05-05 00:00:00+02:00,21.01715850830078,21.59406089782715,20.80828094482422,21.444862365722656,15.291584968566895,1420028,0.0,0.0
|
||||
2023-05-08 00:00:00+02:00,21.484647750854492,21.514488220214844,21.245929718017578,21.514488220214844,15.341232299804688,674713,0.0,0.0
|
||||
2023-05-09 00:00:00+02:00,21.663686752319336,21.663686752319336,21.17630386352539,21.444862365722656,15.291584968566895,853724,0.0,0.0
|
||||
2023-05-10 00:00:00+02:00,21.49459457397461,21.663686752319336,21.156410217285156,21.405075073242188,15.263213157653809,826931,0.0,0.0
|
||||
2023-05-11 00:00:00+02:00,21.464754104614258,21.633846282958984,21.106678009033203,21.37523651123047,15.241935729980469,1023400,0.0,0.0
|
||||
2023-05-12 00:00:00+02:00,21.37523651123047,21.43491554260254,21.206144332885742,21.37523651123047,17.269859313964844,847053,2.51,0.0
|
||||
2023-05-15 00:00:00+02:00,21.0469970703125,21.096731185913086,20.788387298583984,20.858013153076172,19.094114303588867,1023546,2.51,0.0
|
||||
2023-05-16 00:00:00+02:00,20.7386531829834,20.76849365234375,20.281110763549805,20.310949325561523,18.593313217163086,1280267,0.0,0.0
|
||||
2023-05-17 00:00:00+02:00,20.201536178588867,20.57950782775879,20.092124938964844,20.549667358398438,18.811845779418945,1106539,0.0,0.0
|
||||
2023-05-18 00:00:00+02:00,20.72870635986328,20.818225860595703,20.539722442626953,20.678974151611328,18.93021583557129,704356,0.0,0.0
|
||||
2023-05-19 00:00:00+02:00,20.818225860595703,20.897798538208008,20.66902732849121,20.72870635986328,18.97574234008789,1030030,0.0,0.0
|
||||
2023-05-22 00:00:00+02:00,20.66902732849121,20.788387298583984,20.57950782775879,20.76849365234375,19.01216697692871,853879,0.0,0.0
|
||||
2023-05-23 00:00:00+02:00,20.748600006103516,20.80828094482422,20.66902732849121,20.79833221435547,19.039480209350586,779729,0.0,0.0
|
||||
2023-05-24 00:00:00+02:00,20.60934829711914,20.60934829711914,20.291057586669922,20.489988327026367,18.757213592529297,846847,0.0,0.0
|
||||
2023-05-25 00:00:00+02:00,20.51982879638672,20.51982879638672,19.962818145751953,20.01255226135254,18.320152282714844,1017197,0.0,0.0
|
||||
2023-05-26 00:00:00+02:00,20.141857147216797,20.26121711730957,19.885236740112305,20.191591262817383,18.48404884338379,1058894,0.0,0.0
|
||||
2023-05-29 00:00:00+02:00,20.301002502441406,20.340789794921875,20.181644439697266,20.26121711730957,18.547786712646484,295090,0.0,0.0
|
||||
2023-05-30 00:00:00+02:00,20.301002502441406,20.340789794921875,20.052337646484375,20.092124938964844,18.392993927001953,641576,0.0,0.0
|
||||
2023-05-31 00:00:00+02:00,19.77781105041504,19.77781105041504,19.184995651245117,19.427692413330078,17.784751892089844,3164263,0.0,0.0
|
||||
2023-06-01 00:00:00+02:00,19.614688873291016,19.698240280151367,19.475435256958008,19.68232536315918,18.017852783203125,876148,0.0,0.0
|
||||
2023-06-02 00:00:00+02:00,19.857385635375977,20.499935150146484,19.8255558013916,20.440256118774414,18.711687088012695,1069712,0.0,0.0
|
||||
2023-06-05 00:00:00+02:00,20.529775619506836,20.589454650878906,20.39052391052246,20.499935150146484,18.766319274902344,850280,0.0,0.0
|
||||
2023-06-06 00:00:00+02:00,20.489988327026367,20.66902732849121,20.38057518005371,20.66902732849121,18.921110153198242,646291,0.0,0.0
|
||||
2023-06-07 00:00:00+02:00,20.678974151611328,20.92763900756836,20.569562911987305,20.92763900756836,19.157854080200195,885388,0.0,0.0
|
||||
2023-06-08 00:00:00+02:00,20.877906799316406,21.514488220214844,20.877906799316406,21.186250686645508,19.394594192504883,1247924,0.0,0.0
|
||||
2023-06-09 00:00:00+02:00,21.126571655273438,21.17630386352539,20.46014976501465,20.818225860595703,19.057693481445312,1294412,0.0,0.0
|
||||
2023-06-12 00:00:00+02:00,20.887853622436523,21.08678436279297,20.80828094482422,21.05694580078125,19.27622413635254,932962,0.0,0.0
|
||||
2023-06-13 00:00:00+02:00,21.166357040405273,21.454809188842773,20.907745361328125,21.424968719482422,19.61312484741211,905912,0.0,0.0
|
||||
2023-06-14 00:00:00+02:00,21.862619400024414,21.882511138916016,21.424968719482422,21.514488220214844,19.6950740814209,1696595,0.0,0.0
|
||||
2023-06-15 00:00:00+02:00,21.474702835083008,21.474702835083008,21.01715850830078,21.355342864990234,19.549386978149414,932700,0.0,0.0
|
||||
2023-06-16 00:00:00+02:00,21.444862365722656,21.52443504333496,20.04239273071289,20.569562911987305,18.83005714416504,3430067,0.0,0.0
|
||||
2023-06-19 00:00:00+02:00,20.291057586669922,20.291057586669922,19.932979583740234,19.982711791992188,18.29283332824707,1208865,0.0,0.0
|
||||
2023-06-20 00:00:00+02:00,19.495328903198242,20.121965408325195,19.208866119384766,19.821577072143555,18.145326614379883,2053697,0.0,0.0
|
||||
2023-06-21 00:00:00+02:00,19.845449447631836,19.923032760620117,19.662431716918945,19.923032760620117,18.238201141357422,644074,0.0,0.0
|
||||
2023-06-22 00:00:00+02:00,19.749961853027344,20.022499084472656,19.68232536315918,19.797706604003906,18.123476028442383,667821,0.0,0.0
|
||||
2023-06-23 00:00:00+02:00,19.65447425842285,19.805662155151367,19.539094924926758,19.686304092407227,18.02149200439453,893260,0.0,0.0
|
||||
2023-06-26 00:00:00+02:00,19.757919311523438,20.032445907592773,19.65447425842285,19.982711791992188,18.29283332824707,793819,0.0,0.0
|
||||
2023-06-27 00:00:00+02:00,20.092124938964844,20.211484909057617,19.74200439453125,19.95287322998047,18.265520095825195,871227,0.0,0.0
|
||||
2023-06-28 00:00:00+02:00,20.112018585205078,20.151803970336914,19.865341186523438,19.95287322998047,18.265520095825195,911547,0.0,0.0
|
||||
2023-06-29 00:00:00+02:00,20.01255226135254,20.181644439697266,19.903139114379883,20.092124938964844,18.392993927001953,1053234,0.0,0.0
|
||||
2023-06-30 00:00:00+02:00,20.092124938964844,20.46014976501465,20.092124938964844,20.350736618041992,18.629735946655273,934560,0.0,0.0
|
||||
2023-07-03 00:00:00+02:00,20.301002502441406,20.499935150146484,20.181644439697266,20.26121711730957,18.547786712646484,652308,0.0,0.0
|
||||
2023-07-04 00:00:00+02:00,20.241323471069336,20.241323471069336,20.032445907592773,20.181644439697266,18.474945068359375,483753,0.0,0.0
|
||||
2023-07-05 00:00:00+02:00,20.07223129272461,20.201536178588867,20.002605438232422,20.092124938964844,18.392993927001953,692829,0.0,0.0
|
||||
2023-07-06 00:00:00+02:00,19.903139114379883,20.002605438232422,19.634580612182617,19.74200439453125,18.07248306274414,1098682,0.0,0.0
|
||||
2023-07-07 00:00:00+02:00,19.7181339263916,20.350736618041992,19.7181339263916,20.350736618041992,18.629735946655273,909321,0.0,0.0
|
||||
2023-07-10 00:00:00+02:00,20.221431732177734,20.48004150390625,20.201536178588867,20.241323471069336,18.52957534790039,599989,0.0,0.0
|
||||
2023-07-11 00:00:00+02:00,20.291057586669922,20.60934829711914,20.211484909057617,20.51982879638672,18.784528732299805,514723,0.0,0.0
|
||||
2023-07-12 00:00:00+02:00,20.569562911987305,21.126571655273438,20.529775619506836,21.066890716552734,19.285327911376953,903369,0.0,0.0
|
||||
2023-07-13 00:00:00+02:00,20.967424392700195,21.226036071777344,20.92763900756836,20.967424392700195,19.194272994995117,830319,0.0,0.0
|
||||
2023-07-14 00:00:00+02:00,20.877906799316406,20.897798538208008,20.301002502441406,20.301002502441406,18.58420753479004,959780,0.0,0.0
|
||||
2023-07-17 00:00:00+02:00,20.191591262817383,20.330842971801758,20.151803970336914,20.201536178588867,18.493152618408203,678639,0.0,0.0
|
||||
2023-07-18 00:00:00+02:00,20.211484909057617,20.410415649414062,20.112018585205078,20.410415649414062,18.684368133544922,696082,0.0,0.0
|
||||
2023-07-19 00:00:00+02:00,20.340789794921875,20.430309295654297,20.04239273071289,20.310949325561523,18.593313217163086,1027451,0.0,0.0
|
||||
2023-07-20 00:00:00+02:00,20.330842971801758,20.589454650878906,20.330842971801758,20.589454650878906,18.8482666015625,771530,0.0,0.0
|
||||
2023-07-21 00:00:00+02:00,20.569562911987305,20.758546829223633,20.499935150146484,20.639188766479492,18.893795013427734,532559,0.0,0.0
|
||||
2023-07-24 00:00:00+02:00,20.529775619506836,20.788387298583984,20.48004150390625,20.778440475463867,19.021270751953125,576946,0.0,0.0
|
||||
2023-07-25 00:00:00+02:00,20.80828094482422,21.156410217285156,20.7386531829834,21.14646339416504,19.358171463012695,815268,0.0,0.0
|
||||
2023-07-26 00:00:00+02:00,21.066890716552734,21.206144332885742,20.867958068847656,20.967424392700195,19.194272994995117,501060,0.0,0.0
|
||||
2023-07-27 00:00:00+02:00,21.01715850830078,21.43491554260254,20.967424392700195,21.39512825012207,19.58580780029297,1024169,0.0,0.0
|
||||
2023-07-28 00:00:00+02:00,21.30561065673828,21.802940368652344,21.255876541137695,21.802940368652344,19.959131240844727,1075428,0.0,0.0
|
||||
2023-07-31 00:00:00+02:00,21.802940368652344,21.912351608276367,21.663686752319336,21.703474044799805,19.868078231811523,1096731,0.0,0.0
|
||||
2023-08-01 00:00:00+02:00,21.59406089782715,21.604007720947266,21.424968719482422,21.424968719482422,19.61312484741211,660286,0.0,0.0
|
||||
2023-08-02 00:00:00+02:00,21.186250686645508,21.58411407470703,21.08678436279297,21.454809188842773,19.64044189453125,858203,0.0,0.0
|
||||
2023-08-03 00:00:00+02:00,21.673633575439453,21.78304672241211,20.01255226135254,20.499935150146484,18.766319274902344,1721865,0.0,0.0
|
||||
2023-08-04 00:00:00+02:00,20.66902732849121,20.718759536743164,20.39052391052246,20.659080505371094,18.912006378173828,610022,0.0,0.0
|
||||
2023-08-07 00:00:00+02:00,20.589454650878906,20.80828094482422,20.45020294189453,20.80828094482422,19.048587799072266,484065,0.0,0.0
|
||||
2023-08-08 00:00:00+02:00,20.688920974731445,20.818225860595703,20.589454650878906,20.678974151611328,18.93021583557129,420797,0.0,0.0
|
||||
2023-08-09 00:00:00+02:00,20.858013153076172,21.037052154541016,20.76849365234375,20.858013153076172,19.094114303588867,550545,0.0,0.0
|
||||
2023-08-10 00:00:00+02:00,20.977371215820312,21.126571655273438,20.858013153076172,20.997264862060547,19.221590042114258,468059,0.0,0.0
|
||||
2023-08-11 00:00:00+02:00,20.877906799316406,21.0271053314209,20.748600006103516,20.758546829223633,19.003061294555664,462374,0.0,0.0
|
||||
2023-08-14 00:00:00+02:00,20.7386531829834,20.848066329956055,20.66902732849121,20.7386531829834,18.984848022460938,668188,0.0,0.0
|
||||
2023-08-15 00:00:00+02:00,20.788387298583984,20.818225860595703,20.430309295654297,20.57950782775879,18.839160919189453,432414,0.0,0.0
|
||||
2023-08-16 00:00:00+02:00,20.539722442626953,20.76849365234375,20.539722442626953,20.70881462097168,18.957534790039062,544437,0.0,0.0
|
||||
2023-08-17 00:00:00+02:00,20.57950782775879,20.76849365234375,20.549667358398438,20.688920974731445,18.939321517944336,564871,0.0,0.0
|
||||
2023-08-18 00:00:00+02:00,20.688920974731445,20.70881462097168,20.291057586669922,20.38057518005371,18.657052993774414,693870,0.0,0.0
|
||||
2023-08-21 00:00:00+02:00,20.39052391052246,20.66902732849121,20.39052391052246,20.569562911987305,18.83005714416504,793311,0.0,0.0
|
||||
2023-08-22 00:00:00+02:00,20.599401473999023,20.907745361328125,20.5098819732666,20.76849365234375,19.01216697692871,650046,0.0,0.0
|
||||
2023-08-23 00:00:00+02:00,20.80828094482422,20.858013153076172,20.330842971801758,20.370630264282227,18.647947311401367,647211,0.0,0.0
|
||||
2023-08-24 00:00:00+02:00,20.45020294189453,20.599401473999023,20.291057586669922,20.330842971801758,18.611526489257812,475896,0.0,0.0
|
||||
2023-08-25 00:00:00+02:00,20.301002502441406,20.45020294189453,20.26121711730957,20.291057586669922,18.575105667114258,318928,0.0,0.0
|
||||
2023-08-28 00:00:00+02:00,20.42036247253418,20.549667358398438,20.42036247253418,20.499935150146484,18.766319274902344,332741,0.0,0.0
|
||||
2023-08-29 00:00:00+02:00,20.66902732849121,20.897798538208008,20.66902732849121,20.838119506835938,19.075902938842773,523138,0.0,0.0
|
||||
2023-08-30 00:00:00+02:00,20.838119506835938,21.007211685180664,20.778440475463867,20.907745361328125,19.13964080810547,394929,0.0,0.0
|
||||
2023-08-31 00:00:00+02:00,20.947532653808594,21.36528968811035,20.92763900756836,21.265823364257812,19.467437744140625,2323236,0.0,0.0
|
||||
2023-09-01 00:00:00+02:00,21.255876541137695,21.9322452545166,21.255876541137695,21.87256622314453,20.022871017456055,966179,0.0,0.0
|
||||
2023-09-04 00:00:00+02:00,21.981977462768555,22.021764755249023,21.544328689575195,21.58411407470703,19.75881004333496,643546,0.0,0.0
|
||||
2023-09-05 00:00:00+02:00,21.504541397094727,21.78304672241211,21.424968719482422,21.6239013671875,19.79523277282715,541345,0.0,0.0
|
||||
2023-09-06 00:00:00+02:00,21.544328689575195,22.111284255981445,21.504541397094727,22.09139060974121,20.223190307617188,851678,0.0,0.0
|
||||
2023-09-07 00:00:00+02:00,21.882511138916016,21.90240478515625,21.424968719482422,21.464754104614258,19.649545669555664,700314,0.0,0.0
|
||||
2023-09-08 00:00:00+02:00,21.574167251586914,21.574167251586914,20.887853622436523,21.235984802246094,19.440122604370117,719356,0.0,0.0
|
||||
2023-09-11 00:00:00+02:00,21.345396041870117,21.564220428466797,21.315555572509766,21.52443504333496,19.704177856445312,524078,0.0,0.0
|
||||
2023-09-12 00:00:00+02:00,21.58411407470703,21.6239013671875,21.11662483215332,21.11662483215332,19.330856323242188,772781,0.0,0.0
|
||||
2023-09-13 00:00:00+02:00,21.0469970703125,21.36528968811035,20.76849365234375,20.818225860595703,19.057693481445312,691035,0.0,0.0
|
||||
2023-09-14 00:00:00+02:00,20.887853622436523,21.196197509765625,20.629241943359375,21.126571655273438,19.339962005615234,578423,0.0,0.0
|
||||
2023-09-15 00:00:00+02:00,21.295663833618164,21.952138900756836,21.295663833618164,21.84272575378418,19.99555206298828,2234985,0.0,0.0
|
||||
2023-09-18 00:00:00+02:00,21.802940368652344,21.84272575378418,21.673633575439453,21.713420867919922,19.87718391418457,856277,0.0,0.0
|
||||
2023-09-19 00:00:00+02:00,21.6437931060791,21.6437931060791,21.39512825012207,21.415021896362305,19.60401725769043,685505,0.0,0.0
|
||||
2023-09-20 00:00:00+02:00,21.52443504333496,21.792993545532227,21.504541397094727,21.74325942993164,19.904497146606445,752488,0.0,0.0
|
||||
2023-09-21 00:00:00+02:00,21.534381866455078,21.574167251586914,21.0271053314209,21.186250686645508,19.394594192504883,722196,0.0,0.0
|
||||
2023-09-22 00:00:00+02:00,21.08678436279297,21.295663833618164,20.95747947692871,21.096731185913086,19.312644958496094,535977,0.0,0.0
|
||||
2023-09-25 00:00:00+02:00,21.037052154541016,21.17630386352539,20.529775619506836,20.788387298583984,19.030376434326172,678523,0.0,0.0
|
||||
2023-09-26 00:00:00+02:00,20.72870635986328,20.72870635986328,20.410415649414062,20.489988327026367,18.757213592529297,999281,0.0,0.0
|
||||
2023-09-27 00:00:00+02:00,20.559614181518555,20.66902732849121,20.440256118774414,20.569562911987305,18.83005714416504,679654,0.0,0.0
|
||||
2023-09-28 00:00:00+02:00,20.57950782775879,20.858013153076172,20.42036247253418,20.80828094482422,19.048587799072266,791858,0.0,0.0
|
||||
2023-09-29 00:00:00+02:00,20.977371215820312,21.07683753967285,20.778440475463867,20.858013153076172,19.094114303588867,1368070,0.0,0.0
|
||||
2023-10-02 00:00:00+02:00,20.877906799316406,20.95747947692871,20.38057518005371,20.489988327026367,18.757213592529297,921943,0.0,0.0
|
||||
2023-10-03 00:00:00+02:00,20.45020294189453,20.559614181518555,20.241323471069336,20.430309295654297,18.70258140563965,870202,0.0,0.0
|
||||
2023-10-04 00:00:00+02:00,20.340789794921875,20.629241943359375,20.23137664794922,20.301002502441406,18.58420753479004,1412955,0.0,0.0
|
||||
2023-10-05 00:00:00+02:00,20.301002502441406,20.410415649414062,20.151803970336914,20.23137664794922,18.520471572875977,552761,0.0,0.0
|
||||
2023-10-06 00:00:00+02:00,20.271163940429688,20.489988327026367,20.17169761657715,20.370630264282227,18.647947311401367,824653,0.0,0.0
|
||||
2023-10-09 00:00:00+02:00,20.201536178588867,20.26121711730957,19.817598342895508,20.201536178588867,18.493152618408203,857112,0.0,0.0
|
||||
2023-10-10 00:00:00+02:00,20.310949325561523,20.619295120239258,20.281110763549805,20.470096588134766,18.739002227783203,881954,0.0,0.0
|
||||
2023-10-11 00:00:00+02:00,20.32089614868164,20.629241943359375,20.32089614868164,20.440256118774414,18.711687088012695,612797,0.0,0.0
|
||||
2023-10-12 00:00:00+02:00,20.569562911987305,20.688920974731445,20.271163940429688,20.32089614868164,18.602420806884766,484462,0.0,0.0
|
||||
2023-10-13 00:00:00+02:00,20.211484909057617,20.470096588134766,20.211484909057617,20.301002502441406,18.58420753479004,538324,0.0,0.0
|
||||
2023-10-16 00:00:00+02:00,20.340789794921875,20.489988327026367,20.26121711730957,20.310949325561523,18.593313217163086,495104,0.0,0.0
|
||||
2023-10-17 00:00:00+02:00,20.241323471069336,20.301002502441406,19.9130859375,20.221431732177734,18.511367797851562,618131,0.0,0.0
|
||||
2023-10-18 00:00:00+02:00,20.191591262817383,20.23137664794922,19.881256103515625,19.881256103515625,18.19995880126953,559829,0.0,0.0
|
||||
2023-10-19 00:00:00+02:00,19.714153289794922,19.84147071838379,19.551029205322266,19.630603790283203,17.970502853393555,708805,0.0,0.0
|
||||
2023-10-20 00:00:00+02:00,19.49930763244629,19.54705047607422,19.296396255493164,19.296396255493164,17.66455841064453,760144,0.0,0.0
|
||||
2023-10-23 00:00:00+02:00,19.3162899017334,19.344141006469727,19.005956649780273,19.16908073425293,17.548009872436523,652032,0.0,0.0
|
||||
2023-10-24 00:00:00+02:00,19.101444244384766,19.232738494873047,18.994020462036133,19.11735725402832,17.500661849975586,565349,0.0,0.0
|
||||
2023-10-25 00:00:00+02:00,19.133272171020508,19.184995651245117,18.882619857788086,19.093486785888672,17.478809356689453,597757,0.0,0.0
|
||||
2023-10-26 00:00:00+02:00,18.882619857788086,19.507265090942383,18.834875106811523,19.403820037841797,17.76289939880371,756208,0.0,0.0
|
||||
2023-10-27 00:00:00+02:00,19.519201278686523,19.75394058227539,19.20488739013672,19.20488739013672,17.58078956604004,767302,0.0,0.0
|
||||
2023-10-30 00:00:00+01:00,19.296396255493164,19.54705047607422,19.296396255493164,19.45156478881836,17.80660629272461,755454,0.0,0.0
|
||||
2023-10-31 00:00:00+01:00,19.455543518066406,19.972766876220703,19.443607330322266,19.84147071838379,18.163537979125977,1249155,0.0,0.0
|
||||
2023-11-01 00:00:00+01:00,19.903139114379883,20.04239273071289,19.551029205322266,19.618667602539062,17.959577560424805,645054,0.0,0.0
|
||||
2023-11-02 00:00:00+01:00,19.734046936035156,20.410415649414062,19.726089477539062,20.141857147216797,18.438520431518555,1414951,0.0,0.0
|
||||
2023-11-03 00:00:00+01:00,19.877277374267578,20.211484909057617,19.165102005004883,19.51124382019043,17.861236572265625,1786173,0.0,0.0
|
||||
2023-11-06 00:00:00+01:00,19.515222549438477,19.78179168701172,19.304353713989258,19.531137466430664,17.87944793701172,1141224,0.0,0.0
|
||||
2023-11-07 00:00:00+01:00,19.42371368408203,19.535114288330078,19.25263214111328,19.35209846496582,17.71554946899414,719557,0.0,0.0
|
||||
2023-11-08 00:00:00+01:00,19.228759765625,19.427692413330078,19.093486785888672,19.320268630981445,17.686412811279297,829203,0.0,0.0
|
||||
2023-11-09 00:00:00+01:00,19.308332443237305,19.903139114379883,19.308332443237305,19.574901580810547,17.919511795043945,1169455,0.0,0.0
|
||||
2023-11-10 00:00:00+01:00,19.479415893554688,19.761898040771484,19.244674682617188,19.761898040771484,18.090694427490234,991826,0.0,0.0
|
||||
2023-11-13 00:00:00+01:00,19.773834228515625,19.857385635375977,19.531137466430664,19.734046936035156,18.06519889831543,980360,0.0,0.0
|
||||
2023-11-14 00:00:00+01:00,19.79372787475586,20.410415649414062,19.78974723815918,20.340789794921875,18.62063217163086,892672,0.0,0.0
|
||||
2023-11-15 00:00:00+01:00,20.36068344116211,20.917692184448242,20.291057586669922,20.917692184448242,19.148746490478516,1168610,0.0,0.0
|
||||
2023-11-16 00:00:00+01:00,20.79833221435547,21.07683753967285,20.549667358398438,20.549667358398438,18.811845779418945,755625,0.0,0.0
|
||||
2023-11-17 00:00:00+01:00,20.549667358398438,20.848066329956055,20.549667358398438,20.559614181518555,18.820951461791992,784037,0.0,0.0
|
||||
2023-11-20 00:00:00+01:00,20.589454650878906,20.887853622436523,20.51982879638672,20.72870635986328,18.97574234008789,946072,0.0,0.0
|
||||
2023-11-21 00:00:00+01:00,20.688920974731445,20.82817268371582,20.470096588134766,20.629241943359375,18.884689331054688,1185330,0.0,0.0
|
||||
2023-11-22 00:00:00+01:00,20.629241943359375,20.838119506835938,20.559614181518555,20.599401473999023,18.85737419128418,1261386,0.0,0.0
|
||||
2023-11-23 00:00:00+01:00,20.599401473999023,20.76849365234375,20.599401473999023,20.7386531829834,18.984848022460938,633558,0.0,0.0
|
||||
2023-11-24 00:00:00+01:00,20.778440475463867,20.92763900756836,20.72870635986328,20.92763900756836,19.157854080200195,719180,0.0,0.0
|
||||
2023-11-27 00:00:00+01:00,20.887853622436523,20.907745361328125,20.51982879638672,20.57950782775879,18.839160919189453,1094505,0.0,0.0
|
||||
2023-11-28 00:00:00+01:00,20.529775619506836,20.66902732849121,20.330842971801758,20.60934829711914,18.866479873657227,1053370,0.0,0.0
|
||||
2023-11-29 00:00:00+01:00,20.60934829711914,21.037052154541016,20.569562911987305,20.977371215820312,19.203378677368164,957061,0.0,0.0
|
||||
2023-11-30 00:00:00+01:00,20.947532653808594,21.27577018737793,20.818225860595703,21.11662483215332,19.330856323242188,2370750,0.0,0.0
|
||||
2023-12-01 00:00:00+01:00,21.166357040405273,21.6437931060791,21.166357040405273,21.604007720947266,19.777023315429688,1195222,0.0,0.0
|
||||
2023-12-04 00:00:00+01:00,21.484647750854492,21.94219207763672,21.464754104614258,21.74325942993164,19.904497146606445,1089262,0.0,0.0
|
||||
2023-12-05 00:00:00+01:00,21.6239013671875,21.9322452545166,21.59406089782715,21.882511138916016,20.03197479248047,1150906,0.0,0.0
|
||||
2023-12-06 00:00:00+01:00,21.882511138916016,22.081443786621094,21.84272575378418,22.041658401489258,20.177663803100586,1090639,0.0,0.0
|
||||
2023-12-07 00:00:00+01:00,22.081443786621094,22.489255905151367,22.041658401489258,22.359949111938477,20.469038009643555,1596696,0.0,0.0
|
||||
2023-12-08 00:00:00+01:00,22.330108642578125,22.479307174682617,21.991924285888672,22.35000228881836,20.459930419921875,1410130,0.0,0.0
|
||||
2023-12-11 00:00:00+01:00,19.450000762939453,23.649999618530273,17.895000457763672,20.6200008392334,18.876230239868164,8998324,0.0,0.0
|
||||
2023-12-12 00:00:00+01:00,20.790000915527344,22.3700008392334,20.75,22.139999389648438,20.26768684387207,3236690,0.0,0.0
|
||||
2023-12-13 00:00:00+01:00,22.489999771118164,24.530000686645508,22.399999618530273,23.950000762939453,21.92462158203125,2215354,0.0,0.0
|
||||
2023-12-14 00:00:00+01:00,24.5,25.010000228881836,23.950000762939453,24.540000915527344,22.4647274017334,1535694,0.0,0.0
|
||||
2023-12-15 00:00:00+01:00,24.8799991607666,25.420000076293945,24.600000381469727,25.40999984741211,23.261154174804688,2385553,0.0,0.0
|
||||
2023-12-18 00:00:00+01:00,25.649999618530273,26.969999313354492,25.489999771118164,26.1299991607666,23.920265197753906,965441,0.0,0.0
|
||||
2023-12-19 00:00:00+01:00,26.290000915527344,27.399999618530273,26.200000762939453,27.209999084472656,24.908933639526367,908754,0.0,0.0
|
||||
2023-12-20 00:00:00+01:00,27.3700008392334,27.469999313354492,26.350000381469727,26.350000381469727,24.121662139892578,821654,0.0,0.0
|
||||
2023-12-21 00:00:00+01:00,26.239999771118164,26.3700008392334,25.760000228881836,26.049999237060547,23.847030639648438,744197,0.0,0.0
|
||||
2023-12-22 00:00:00+01:00,26.1200008392334,26.510000228881836,26.049999237060547,26.239999771118164,24.020963668823242,358134,0.0,0.0
|
||||
2023-12-27 00:00:00+01:00,26.639999389648438,26.729999542236328,26.299999237060547,26.729999542236328,24.469524383544922,398784,0.0,0.0
|
||||
2023-12-28 00:00:00+01:00,26.899999618530273,27.200000762939453,26.899999618530273,27.190000534057617,24.890626907348633,306879,0.0,0.0
|
||||
2023-12-29 00:00:00+01:00,27.219999313354492,27.959999084472656,27.219999313354492,27.729999542236328,25.384958267211914,508827,0.0,0.0
|
||||
2024-01-02 00:00:00+01:00,28.059999465942383,28.600000381469727,27.520000457763672,28.030000686645508,25.659589767456055,395002,0.0,0.0
|
||||
2024-01-03 00:00:00+01:00,28.110000610351562,28.15999984741211,27.170000076293945,27.43000030517578,25.110328674316406,517626,0.0,0.0
|
||||
2024-01-04 00:00:00+01:00,27.5,28.110000610351562,27.5,28.09000015258789,25.714515686035156,353356,0.0,0.0
|
||||
2024-01-05 00:00:00+01:00,28.079999923706055,28.469999313354492,28.0,28.329999923706055,25.93421745300293,426440,0.0,0.0
|
||||
2024-01-08 00:00:00+01:00,28.290000915527344,28.329999923706055,27.540000915527344,28.0,25.632125854492188,503233,0.0,0.0
|
||||
2024-01-09 00:00:00+01:00,27.190000534057617,27.549999237060547,27.079999923706055,27.299999237060547,24.991321563720703,592677,0.0,0.0
|
||||
2024-01-10 00:00:00+01:00,27.100000381469727,27.170000076293945,26.350000381469727,26.350000381469727,24.121662139892578,692877,0.0,0.0
|
||||
2024-01-11 00:00:00+01:00,26.389999389648438,26.559999465942383,25.889999389648438,26.0,23.801258087158203,631805,0.0,0.0
|
||||
2024-01-12 00:00:00+01:00,26.639999389648438,26.860000610351562,26.06999969482422,26.139999389648438,23.929418563842773,803481,0.0,0.0
|
||||
2024-01-15 00:00:00+01:00,25.059999465942383,25.329999923706055,25.0,25.299999237060547,24.690631866455078,726646,1.62,0.0
|
||||
2024-01-16 00:00:00+01:00,25.149999618530273,25.200000762939453,24.579999923706055,24.989999771118164,24.388099670410156,493029,0.0,0.0
|
||||
2024-01-17 00:00:00+01:00,24.700000762939453,24.729999542236328,23.989999771118164,24.260000228881836,23.675682067871094,646371,0.0,0.0
|
||||
2024-01-18 00:00:00+01:00,24.200000762939453,24.239999771118164,23.530000686645508,23.530000686645508,22.963266372680664,686723,0.0,0.0
|
||||
2024-01-19 00:00:00+01:00,23.670000076293945,24.25,23.670000076293945,24.049999237060547,23.470739364624023,679303,0.0,0.0
|
||||
2024-01-22 00:00:00+01:00,24.299999237060547,24.770000457763672,24.079999923706055,24.760000228881836,24.163639068603516,282294,0.0,0.0
|
||||
2024-01-23 00:00:00+01:00,25.200000762939453,25.450000762939453,24.90999984741211,25.3799991607666,24.768705368041992,397643,0.0,0.0
|
||||
2024-01-24 00:00:00+01:00,25.600000381469727,25.6299991607666,24.75,24.75,24.153881072998047,564082,0.0,0.0
|
||||
2024-01-25 00:00:00+01:00,24.84000015258789,25.760000228881836,24.799999237060547,25.600000381469727,24.983407974243164,401178,0.0,0.0
|
||||
2024-01-26 00:00:00+01:00,25.690000534057617,26.959999084472656,25.6200008392334,26.40999984741211,25.773897171020508,712857,0.0,0.0
|
||||
2024-01-29 00:00:00+01:00,26.5,26.549999237060547,25.760000228881836,25.760000228881836,25.139554977416992,375526,0.0,0.0
|
||||
2024-01-30 00:00:00+01:00,25.8799991607666,26.049999237060547,25.610000610351562,25.690000534057617,25.071239471435547,339731,0.0,0.0
|
||||
2024-01-31 00:00:00+01:00,25.850000381469727,26.1299991607666,25.440000534057617,25.440000534057617,24.827260971069336,1756316,0.0,0.0
|
||||
2024-02-01 00:00:00+01:00,25.329999923706055,25.5,24.530000686645508,24.59000015258789,23.99773406982422,398800,0.0,0.0
|
||||
2024-02-02 00:00:00+01:00,24.899999618530273,24.979999542236328,24.40999984741211,24.40999984741211,23.82206916809082,418661,0.0,0.0
|
||||
2024-02-05 00:00:00+01:00,24.440000534057617,24.56999969482422,23.6299991607666,23.649999618530273,23.080373764038086,640546,0.0,0.0
|
||||
2024-02-06 00:00:00+01:00,23.739999771118164,23.81999969482422,22.8799991607666,23.469999313354492,22.904708862304688,800098,0.0,0.0
|
||||
2024-02-07 00:00:00+01:00,23.200000762939453,23.309999465942383,22.489999771118164,22.639999389648438,22.09469985961914,896379,0.0,0.0
|
||||
2024-02-08 00:00:00+01:00,22.799999237060547,23.1299991607666,22.690000534057617,23.0,22.446029663085938,622376,0.0,0.0
|
||||
2024-02-09 00:00:00+01:00,22.5,22.739999771118164,22.209999084472656,22.209999084472656,21.67505645751953,783024,0.0,0.0
|
||||
2024-02-12 00:00:00+01:00,22.450000762939453,22.899999618530273,22.290000915527344,22.84000015258789,22.289884567260742,443790,0.0,0.0
|
||||
2024-02-13 00:00:00+01:00,22.860000610351562,23.34000015258789,22.719999313354492,23.190000534057617,22.631454467773438,530025,0.0,0.0
|
||||
2024-02-14 00:00:00+01:00,23.06999969482422,23.5,22.90999984741211,23.489999771118164,22.92422866821289,452602,0.0,0.0
|
||||
2024-02-15 00:00:00+01:00,23.6200008392334,24.170000076293945,23.579999923706055,23.940000534057617,23.36338996887207,423885,0.0,0.0
|
||||
2024-02-16 00:00:00+01:00,24.280000686645508,24.420000076293945,23.770000457763672,24.020000457763672,23.441463470458984,445071,0.0,0.0
|
||||
2024-02-19 00:00:00+01:00,24.110000610351562,24.139999389648438,23.690000534057617,23.690000534057617,23.11941146850586,334433,0.0,0.0
|
||||
2024-02-20 00:00:00+01:00,23.770000457763672,24.09000015258789,23.489999771118164,24.09000015258789,23.509777069091797,306827,0.0,0.0
|
||||
2024-02-21 00:00:00+01:00,23.850000381469727,24.040000915527344,23.5,24.040000915527344,23.460981369018555,431924,0.0,0.0
|
||||
2024-02-22 00:00:00+01:00,24.229999542236328,24.399999618530273,24.010000228881836,24.219999313354492,23.63664436340332,366743,0.0,0.0
|
||||
2024-02-23 00:00:00+01:00,24.239999771118164,24.6200008392334,23.860000610351562,23.959999084472656,23.38290786743164,266603,0.0,0.0
|
||||
2024-02-26 00:00:00+01:00,23.959999084472656,23.959999084472656,23.270000457763672,23.479999542236328,22.91446876525879,316183,0.0,0.0
|
||||
2024-02-27 00:00:00+01:00,23.540000915527344,23.889999389648438,23.329999923706055,23.75,23.17796516418457,284263,0.0,0.0
|
||||
2024-02-28 00:00:00+01:00,23.829999923706055,24.059999465942383,23.559999465942383,23.6200008392334,23.051097869873047,344714,0.0,0.0
|
||||
2024-02-29 00:00:00+01:00,23.600000381469727,23.6299991607666,23.329999923706055,23.5,22.93398666381836,601749,0.0,0.0
|
||||
2024-03-01 00:00:00+01:00,23.6299991607666,24.530000686645508,23.59000015258789,24.200000762939453,23.617128372192383,445507,0.0,0.0
|
||||
2024-03-04 00:00:00+01:00,24.1200008392334,24.229999542236328,22.989999771118164,23.3799991607666,22.816877365112305,469234,0.0,0.0
|
||||
2024-03-05 00:00:00+01:00,23.329999923706055,23.579999923706055,23.079999923706055,23.579999923706055,23.012060165405273,321295,0.0,0.0
|
||||
2024-03-06 00:00:00+01:00,23.579999923706055,24.100000381469727,23.549999237060547,23.549999237060547,22.9827823638916,516710,0.0,0.0
|
||||
2024-03-07 00:00:00+01:00,23.389999389648438,23.670000076293945,23.100000381469727,23.5,22.93398666381836,371579,0.0,0.0
|
||||
2024-03-08 00:00:00+01:00,23.520000457763672,23.770000457763672,22.969999313354492,23.739999771118164,23.1682071685791,426367,0.0,0.0
|
||||
2024-03-11 00:00:00+01:00,23.68000030517578,24.100000381469727,23.450000762939453,24.100000381469727,23.5195369720459,437456,0.0,0.0
|
||||
2024-03-12 00:00:00+01:00,24.299999237060547,25.450000762939453,24.059999465942383,25.25,24.64183807373047,794906,0.0,0.0
|
||||
2024-03-13 00:00:00+01:00,24.100000381469727,26.010000228881836,23.950000762939453,24.549999237060547,23.958696365356445,844838,0.0,0.0
|
||||
2024-03-14 00:00:00+01:00,24.440000534057617,24.729999542236328,23.649999618530273,23.81999969482422,23.246280670166016,643203,0.0,0.0
|
||||
2024-03-15 00:00:00+01:00,23.850000381469727,24.579999923706055,23.229999542236328,23.229999542236328,22.670490264892578,1376963,0.0,0.0
|
||||
2024-03-18 00:00:00+01:00,23.229999542236328,23.6299991607666,23.030000686645508,23.440000534057617,22.87543296813965,406545,0.0,0.0
|
||||
2024-03-19 00:00:00+01:00,23.149999618530273,23.75,23.040000915527344,23.670000076293945,23.09989356994629,429140,0.0,0.0
|
||||
2024-03-20 00:00:00+01:00,23.639999389648438,24.110000610351562,23.5,24.030000686645508,23.451223373413086,308989,0.0,0.0
|
||||
2024-03-21 00:00:00+01:00,24.18000030517578,24.479999542236328,24.030000686645508,24.15999984741211,23.57809066772461,415990,0.0,0.0
|
||||
2024-03-22 00:00:00+01:00,24.139999389648438,24.719999313354492,23.84000015258789,24.540000915527344,23.948938369750977,295245,0.0,0.0
|
||||
2024-03-25 00:00:00+01:00,24.549999237060547,25.100000381469727,24.520000457763672,25.059999465942383,24.45641326904297,348983,0.0,0.0
|
||||
2024-03-26 00:00:00+01:00,25.030000686645508,25.09000015258789,24.299999237060547,24.549999237060547,23.958696365356445,323207,0.0,0.0
|
||||
2024-03-27 00:00:00+01:00,24.459999084472656,24.969999313354492,24.31999969482422,24.969999313354492,24.368581771850586,203281,0.0,0.0
|
||||
2024-03-28 00:00:00+01:00,25.020000457763672,25.360000610351562,24.700000762939453,25.299999237060547,24.690631866455078,292668,0.0,0.0
|
||||
2024-04-02 00:00:00+02:00,25.350000381469727,25.799999237060547,25.299999237060547,25.600000381469727,24.983407974243164,302238,0.0,0.0
|
||||
2024-04-03 00:00:00+02:00,25.68000030517578,26.8799991607666,25.6299991607666,26.690000534057617,26.047155380249023,448326,0.0,0.0
|
||||
2024-04-04 00:00:00+02:00,28.5,29.190000534057617,27.709999084472656,27.709999084472656,27.042585372924805,1493843,0.0,0.0
|
||||
2024-04-05 00:00:00+02:00,27.350000381469727,27.959999084472656,27.010000228881836,27.350000381469727,26.69125747680664,540908,0.0,0.0
|
||||
2024-04-08 00:00:00+02:00,27.399999618530273,28.309999465942383,27.34000015258789,28.270000457763672,27.589099884033203,487088,0.0,0.0
|
||||
2024-04-09 00:00:00+02:00,28.350000381469727,28.43000030517578,28.049999237060547,28.200000762939453,27.52078628540039,253999,0.0,0.0
|
||||
2024-04-10 00:00:00+02:00,28.34000015258789,29.40999984741211,28.1200008392334,28.639999389648438,27.950185775756836,735134,0.0,0.0
|
||||
2024-04-11 00:00:00+02:00,28.93000030517578,29.260000228881836,28.649999618530273,28.959999084472656,28.262479782104492,306645,0.0,0.0
|
||||
2024-04-12 00:00:00+02:00,29.399999618530273,29.799999237060547,29.170000076293945,29.5,28.789474487304688,437731,0.0,0.0
|
||||
2024-04-15 00:00:00+02:00,29.100000381469727,29.850000381469727,29.0,29.450000762939453,28.740678787231445,388339,0.0,0.0
|
||||
2024-04-16 00:00:00+02:00,29.200000762939453,29.350000381469727,28.780000686645508,28.780000686645508,28.086816787719727,434787,0.0,0.0
|
||||
2024-04-17 00:00:00+02:00,28.780000686645508,29.989999771118164,28.760000228881836,29.799999237060547,29.082246780395508,352161,0.0,0.0
|
||||
2024-04-18 00:00:00+02:00,29.899999618530273,30.700000762939453,29.780000686645508,30.649999618530273,29.911775588989258,347317,0.0,0.0
|
||||
2024-04-19 00:00:00+02:00,30.5,31.040000915527344,28.34000015258789,30.75,30.009366989135742,697878,0.0,0.0
|
||||
2024-04-22 00:00:00+02:00,30.81999969482422,31.600000381469727,30.770000457763672,31.56999969482422,30.809616088867188,401308,0.0,0.0
|
||||
2024-04-23 00:00:00+02:00,31.579999923706055,31.65999984741211,30.049999237060547,31.0,30.253345489501953,471634,0.0,0.0
|
||||
2024-04-24 00:00:00+02:00,30.950000762939453,31.75,30.90999984741211,31.200000762939453,30.448528289794922,307607,0.0,0.0
|
||||
2024-04-25 00:00:00+02:00,31.299999237060547,31.329999923706055,29.670000076293945,29.75,29.0334529876709,478021,0.0,0.0
|
||||
2024-04-26 00:00:00+02:00,30.25,30.719999313354492,29.959999084472656,30.18000030517578,29.453096389770508,331898,0.0,0.0
|
||||
2024-04-29 00:00:00+02:00,30.209999084472656,30.899999618530273,30.209999084472656,30.850000381469727,30.106958389282227,225725,0.0,0.0
|
||||
2024-04-30 00:00:00+02:00,30.899999618530273,31.18000030517578,30.290000915527344,30.40999984741211,29.677555084228516,232054,0.0,0.0
|
||||
2024-05-02 00:00:00+02:00,30.40999984741211,30.600000381469727,29.709999084472656,30.5,29.76538848876953,390674,0.0,0.0
|
||||
2024-05-03 00:00:00+02:00,29.56999969482422,30.299999237060547,29.5,30.139999389648438,29.414058685302734,364126,0.0,0.0
|
||||
2024-05-06 00:00:00+02:00,30.290000915527344,30.989999771118164,30.139999389648438,30.420000076293945,29.687314987182617,273816,0.0,0.0
|
||||
2024-05-07 00:00:00+02:00,31.600000381469727,35.25,31.360000610351562,34.7599983215332,33.92278289794922,1075584,0.0,0.0
|
||||
2024-05-08 00:00:00+02:00,34.34000015258789,36.619998931884766,33.43000030517578,34.68000030517578,33.84471130371094,1057246,0.0,0.0
|
||||
2024-05-09 00:00:00+02:00,34.650001525878906,35.33000183105469,34.209999084472656,34.38999938964844,33.56169509887695,262471,0.0,0.0
|
||||
2024-05-10 00:00:00+02:00,34.790000915527344,34.939998626708984,33.58000183105469,33.650001525878906,32.83951950073242,223080,0.0,0.0
|
||||
2024-05-13 00:00:00+02:00,33.5,34.459999084472656,33.33000183105469,34.310001373291016,33.48362350463867,273103,0.0,0.0
|
||||
2024-05-14 00:00:00+02:00,34.220001220703125,34.52000045776367,33.560001373291016,34.52000045776367,33.68856430053711,279550,0.0,0.0
|
||||
2024-05-15 00:00:00+02:00,34.630001068115234,34.900001525878906,33.75,34.099998474121094,33.27867889404297,242453,0.0,0.0
|
||||
2024-05-16 00:00:00+02:00,34.13999938964844,34.13999938964844,33.04999923706055,33.599998474121094,32.79072189331055,235321,0.0,0.0
|
||||
2024-05-17 00:00:00+02:00,32.84000015258789,34.06999969482422,32.59000015258789,34.06999969482422,33.2494010925293,339910,0.0,0.0
|
||||
2024-05-20 00:00:00+02:00,34.400001525878906,34.400001525878906,33.70000076293945,34.04999923706055,33.229881286621094,164887,0.0,0.0
|
||||
2024-05-21 00:00:00+02:00,33.97999954223633,34.130001068115234,33.31999969482422,33.31999969482422,32.5174674987793,171162,0.0,0.0
|
||||
2024-05-22 00:00:00+02:00,33.29999923706055,34.189998626708984,32.93000030517578,34.189998626708984,33.366512298583984,345186,0.0,0.0
|
||||
2024-05-23 00:00:00+02:00,34.189998626708984,34.75,34.150001525878906,34.470001220703125,33.6397705078125,301874,0.0,0.0
|
||||
2024-05-24 00:00:00+02:00,34.29999923706055,35.040000915527344,34.060001373291016,34.52000045776367,33.68856430053711,297474,0.0,0.0
|
||||
2024-05-27 00:00:00+02:00,34.52000045776367,34.900001525878906,34.25,34.5,33.669044494628906,145496,0.0,0.0
|
||||
2024-05-28 00:00:00+02:00,34.459999084472656,34.540000915527344,33.81999969482422,34.400001525878906,33.57145690917969,239174,0.0,0.0
|
||||
2024-05-29 00:00:00+02:00,34.400001525878906,34.439998626708984,33.900001525878906,34.220001220703125,33.395790100097656,245711,0.0,0.0
|
||||
2024-05-30 00:00:00+02:00,34.61000061035156,34.61000061035156,33.75,34.310001373291016,33.48362350463867,270049,0.0,0.0
|
||||
2024-05-31 00:00:00+02:00,34.25,34.650001525878906,33.45000076293945,33.630001068115234,32.81999969482422,348292,0.0,0.0
|
||||
2024-06-03 00:00:00+02:00,33.20000076293945,33.290000915527344,31.81999969482422,31.829999923706055,31.829999923706055,271111,0.81,0.0
|
||||
2024-06-04 00:00:00+02:00,31.780000686645508,31.860000610351562,31.260000228881836,31.649999618530273,31.649999618530273,345119,0.0,0.0
|
||||
2024-06-05 00:00:00+02:00,31.770000457763672,31.940000534057617,31.270000457763672,31.270000457763672,31.270000457763672,371491,0.0,0.0
|
||||
2024-06-06 00:00:00+02:00,31.489999771118164,31.510000228881836,30.600000381469727,30.920000076293945,30.920000076293945,325501,0.0,0.0
|
||||
2024-06-07 00:00:00+02:00,30.90999984741211,31.209999084472656,30.600000381469727,30.969999313354492,30.969999313354492,161556,0.0,0.0
|
||||
2024-06-10 00:00:00+02:00,30.850000381469727,31.739999771118164,30.729999542236328,31.739999771118164,31.739999771118164,265293,0.0,0.0
|
||||
2024-06-11 00:00:00+02:00,31.639999389648438,32.529998779296875,31.639999389648438,32.349998474121094,32.349998474121094,424271,0.0,0.0
|
||||
2024-06-12 00:00:00+02:00,32.40999984741211,33.04999923706055,32.40999984741211,32.81999969482422,32.81999969482422,244552,0.0,0.0
|
||||
2024-06-13 00:00:00+02:00,32.54999923706055,32.54999923706055,31.709999084472656,31.780000686645508,31.780000686645508,302052,0.0,0.0
|
||||
2024-06-14 00:00:00+02:00,31.600000381469727,31.6299991607666,30.34000015258789,30.790000915527344,30.790000915527344,342157,0.0,0.0
|
||||
2024-06-17 00:00:00+02:00,30.920000076293945,31.479999542236328,30.889999389648438,31.34000015258789,31.34000015258789,273690,0.0,0.0
|
||||
2024-06-18 00:00:00+02:00,31.579999923706055,31.690000534057617,31.06999969482422,31.229999542236328,31.229999542236328,218534,0.0,0.0
|
||||
2024-06-19 00:00:00+02:00,31.260000228881836,31.81999969482422,31.200000762939453,31.350000381469727,31.350000381469727,175454,0.0,0.0
|
||||
2024-06-20 00:00:00+02:00,31.31999969482422,32.11000061035156,31.31999969482422,31.709999084472656,31.709999084472656,296995,0.0,0.0
|
||||
2024-06-21 00:00:00+02:00,31.860000610351562,32.04999923706055,31.559999465942383,31.719999313354492,31.719999313354492,2005373,0.0,0.0
|
||||
2024-06-24 00:00:00+02:00,31.700000762939453,33.630001068115234,31.700000762939453,33.06999969482422,33.06999969482422,347579,0.0,0.0
|
||||
2024-06-25 00:00:00+02:00,33.0,33.34000015258789,31.90999984741211,31.90999984741211,31.90999984741211,241894,0.0,0.0
|
||||
2024-06-26 00:00:00+02:00,31.899999618530273,32.349998474121094,31.649999618530273,31.8700008392334,31.8700008392334,267568,0.0,0.0
|
||||
2024-06-27 00:00:00+02:00,32.29999923706055,33.0,32.20000076293945,32.900001525878906,32.900001525878906,182682,0.0,0.0
|
||||
2024-06-28 00:00:00+02:00,32.95000076293945,33.060001373291016,32.31999969482422,32.869998931884766,32.869998931884766,277611,0.0,0.0
|
||||
2024-07-01 00:00:00+02:00,33.29999923706055,33.4900016784668,32.72999954223633,33.4900016784668,33.4900016784668,206747,0.0,0.0
|
||||
2024-07-02 00:00:00+02:00,33.5,34.0,33.13999938964844,34.0,34.0,231379,0.0,0.0
|
||||
2024-07-03 00:00:00+02:00,33.95000076293945,34.13999938964844,33.47999954223633,34.13999938964844,34.13999938964844,262502,0.0,0.0
|
||||
2024-07-04 00:00:00+02:00,34.0,34.20000076293945,33.540000915527344,34.060001373291016,34.060001373291016,130465,0.0,0.0
|
||||
2024-07-05 00:00:00+02:00,34.060001373291016,34.279998779296875,33.5099983215332,33.5099983215332,33.5099983215332,212429,0.0,0.0
|
||||
2024-07-08 00:00:00+02:00,33.400001525878906,33.95000076293945,32.81999969482422,33.95000076293945,33.95000076293945,194477,0.0,0.0
|
||||
2024-07-09 00:00:00+02:00,33.790000915527344,34.060001373291016,32.290000915527344,32.5099983215332,32.5099983215332,364262,0.0,0.0
|
||||
2024-07-10 00:00:00+02:00,32.29999923706055,32.38999938964844,31.75,32.040000915527344,32.040000915527344,207620,0.0,0.0
|
||||
2024-07-11 00:00:00+02:00,32.11000061035156,32.599998474121094,32.06999969482422,32.349998474121094,32.349998474121094,159663,0.0,0.0
|
||||
2024-07-12 00:00:00+02:00,32.29999923706055,32.93000030517578,32.29999923706055,32.59000015258789,32.59000015258789,116583,0.0,0.0
|
||||
2024-07-15 00:00:00+02:00,32.459999084472656,32.689998626708984,31.899999618530273,32.279998779296875,32.279998779296875,123588,0.0,0.0
|
||||
2024-07-16 00:00:00+02:00,32.20000076293945,32.65999984741211,31.940000534057617,32.45000076293945,32.45000076293945,88377,0.0,0.0
|
||||
2024-07-17 00:00:00+02:00,32.72999954223633,33.939998626708984,32.040000915527344,33.939998626708984,33.939998626708984,222062,0.0,0.0
|
||||
2024-07-18 00:00:00+02:00,34.0,34.93000030517578,33.79999923706055,34.63999938964844,34.63999938964844,400707,0.0,0.0
|
||||
2024-07-19 00:00:00+02:00,34.290000915527344,34.36000061035156,33.529998779296875,34.0099983215332,34.0099983215332,188494,0.0,0.0
|
||||
2024-07-22 00:00:00+02:00,34.349998474121094,34.5,33.66999816894531,34.13999938964844,34.13999938964844,144759,0.0,0.0
|
||||
2024-07-23 00:00:00+02:00,33.95000076293945,34.02000045776367,33.5,33.83000183105469,33.83000183105469,99602,0.0,0.0
|
||||
2024-07-24 00:00:00+02:00,33.54999923706055,33.97999954223633,33.459999084472656,33.5099983215332,33.5099983215332,118200,0.0,0.0
|
||||
2024-07-25 00:00:00+02:00,33.400001525878906,33.75,32.43000030517578,33.41999816894531,33.41999816894531,143724,0.0,0.0
|
||||
2024-07-26 00:00:00+02:00,33.09000015258789,33.439998626708984,32.650001525878906,33.2599983215332,33.2599983215332,150065,0.0,0.0
|
||||
2024-07-29 00:00:00+02:00,33.25,33.560001373291016,33.06999969482422,33.18000030517578,33.18000030517578,101941,0.0,0.0
|
||||
2024-07-30 00:00:00+02:00,33.0,33.619998931884766,32.86000061035156,33.18000030517578,33.18000030517578,142743,0.0,0.0
|
||||
2024-07-31 00:00:00+02:00,33.849998474121094,34.0,32.20000076293945,32.52000045776367,32.52000045776367,561976,0.0,0.0
|
||||
2024-08-01 00:00:00+02:00,32.13999938964844,32.599998474121094,31.190000534057617,31.469999313354492,31.469999313354492,275048,0.0,0.0
|
||||
2024-08-02 00:00:00+02:00,31.229999542236328,31.760000228881836,30.860000610351562,30.860000610351562,30.860000610351562,265760,0.0,0.0
|
||||
2024-08-05 00:00:00+02:00,30.100000381469727,30.479999542236328,29.469999313354492,29.940000534057617,29.940000534057617,473460,0.0,0.0
|
||||
2024-08-06 00:00:00+02:00,30.5,31.010000228881836,30.040000915527344,30.190000534057617,30.190000534057617,264982,0.0,0.0
|
||||
2024-08-07 00:00:00+02:00,30.510000228881836,31.229999542236328,30.3799991607666,30.889999389648438,30.889999389648438,178311,0.0,0.0
|
||||
2024-08-08 00:00:00+02:00,30.799999237060547,30.959999084472656,30.40999984741211,30.799999237060547,30.799999237060547,172146,0.0,0.0
|
||||
2024-08-09 00:00:00+02:00,30.90999984741211,31.520000457763672,30.90999984741211,31.15999984741211,31.15999984741211,179785,0.0,0.0
|
||||
2024-08-12 00:00:00+02:00,31.299999237060547,31.690000534057617,30.59000015258789,30.59000015258789,30.59000015258789,132932,0.0,0.0
|
||||
2024-08-13 00:00:00+02:00,30.690000534057617,31.040000915527344,30.360000610351562,30.600000381469727,30.600000381469727,103593,0.0,0.0
|
||||
2024-08-14 00:00:00+02:00,30.649999618530273,30.68000030517578,30.059999465942383,30.479999542236328,30.479999542236328,209068,0.0,0.0
|
||||
2024-08-15 00:00:00+02:00,30.549999237060547,31.09000015258789,30.450000762939453,30.920000076293945,30.920000076293945,125365,0.0,0.0
|
||||
2024-08-16 00:00:00+02:00,30.940000534057617,31.1200008392334,30.729999542236328,30.8799991607666,30.8799991607666,141253,0.0,0.0
|
||||
2024-08-19 00:00:00+02:00,31.030000686645508,31.299999237060547,30.670000076293945,31.030000686645508,31.030000686645508,180272,0.0,0.0
|
||||
2024-08-20 00:00:00+02:00,31.170000076293945,31.170000076293945,30.469999313354492,30.530000686645508,30.530000686645508,152575,0.0,0.0
|
||||
2024-08-21 00:00:00+02:00,30.530000686645508,31.020000457763672,30.530000686645508,30.969999313354492,30.969999313354492,128994,0.0,0.0
|
||||
2024-08-22 00:00:00+02:00,30.979999542236328,31.3799991607666,30.780000686645508,31.229999542236328,31.229999542236328,87006,0.0,0.0
|
||||
2024-08-23 00:00:00+02:00,31.18000030517578,31.540000915527344,31.18000030517578,31.270000457763672,31.270000457763672,84423,0.0,0.0
|
||||
2024-08-26 00:00:00+02:00,31.149999618530273,31.459999084472656,30.829999923706055,31.030000686645508,31.030000686645508,72965,0.0,0.0
|
||||
2024-08-27 00:00:00+02:00,30.90999984741211,31.360000610351562,30.809999465942383,31.139999389648438,31.139999389648438,102326,0.0,0.0
|
||||
2024-08-28 00:00:00+02:00,31.139999389648438,31.190000534057617,30.540000915527344,30.93000030517578,30.93000030517578,133750,0.0,0.0
|
||||
2024-08-29 00:00:00+02:00,30.81999969482422,31.25,30.81999969482422,31.079999923706055,31.079999923706055,110738,0.0,0.0
|
||||
2024-08-30 00:00:00+02:00,31.190000534057617,31.829999923706055,31.079999923706055,31.700000762939453,31.700000762939453,222082,0.0,0.0
|
||||
2024-09-02 00:00:00+02:00,31.739999771118164,32.36000061035156,31.469999313354492,32.18000030517578,32.18000030517578,137822,0.0,0.0
|
||||
2024-09-03 00:00:00+02:00,32.04999923706055,32.2400016784668,31.469999313354492,31.520000457763672,31.520000457763672,115050,0.0,0.0
|
||||
2024-09-04 00:00:00+02:00,31.100000381469727,31.739999771118164,31.030000686645508,31.559999465942383,31.559999465942383,110471,0.0,0.0
|
||||
2024-09-05 00:00:00+02:00,31.34000015258789,32.310001373291016,31.34000015258789,31.670000076293945,31.670000076293945,230413,0.0,0.0
|
||||
2024-09-06 00:00:00+02:00,31.489999771118164,31.8700008392334,31.18000030517578,31.209999084472656,31.209999084472656,163894,0.0,0.0
|
||||
2024-09-09 00:00:00+02:00,31.5,31.729999542236328,31.280000686645508,31.649999618530273,31.649999618530273,150347,0.0,0.0
|
||||
2024-09-10 00:00:00+02:00,31.59000015258789,32.040000915527344,30.8700008392334,30.8700008392334,30.8700008392334,177060,0.0,0.0
|
||||
2024-09-11 00:00:00+02:00,30.93000030517578,32.06999969482422,30.93000030517578,31.049999237060547,31.049999237060547,253253,0.0,0.0
|
||||
2024-09-12 00:00:00+02:00,31.049999237060547,31.3799991607666,30.809999465942383,30.809999465942383,30.809999465942383,198487,0.0,0.0
|
||||
2024-09-13 00:00:00+02:00,30.809999465942383,31.6299991607666,30.809999465942383,31.3700008392334,31.3700008392334,160154,0.0,0.0
|
||||
2024-09-16 00:00:00+02:00,31.270000457763672,31.469999313354492,31.100000381469727,31.450000762939453,31.450000762939453,112962,0.0,0.0
|
||||
2024-09-17 00:00:00+02:00,31.719999313354492,32.75,31.719999313354492,32.75,32.75,181018,0.0,0.0
|
||||
2024-09-18 00:00:00+02:00,32.81999969482422,33.84000015258789,32.38999938964844,33.72999954223633,33.72999954223633,208825,0.0,0.0
|
||||
2024-09-19 00:00:00+02:00,34.119998931884766,34.689998626708984,33.84000015258789,34.58000183105469,34.58000183105469,292983,0.0,0.0
|
||||
2024-09-20 00:00:00+02:00,34.599998474121094,34.599998474121094,33.93000030517578,34.279998779296875,34.279998779296875,547234,0.0,0.0
|
||||
2024-09-23 00:00:00+02:00,34.22999954223633,34.68000030517578,34.11000061035156,34.369998931884766,34.369998931884766,148293,0.0,0.0
|
||||
2024-09-24 00:00:00+02:00,34.709999084472656,35.13999938964844,34.279998779296875,34.279998779296875,34.279998779296875,214647,0.0,0.0
|
||||
2024-09-25 00:00:00+02:00,34.279998779296875,34.83000183105469,33.58000183105469,33.58000183105469,33.58000183105469,194543,0.0,0.0
|
||||
2024-09-26 00:00:00+02:00,34.0,34.119998931884766,33.650001525878906,34.119998931884766,34.119998931884766,198143,0.0,0.0
|
||||
2024-09-27 00:00:00+02:00,34.2400016784668,35.02000045776367,34.130001068115234,34.63999938964844,34.63999938964844,196448,0.0,0.0
|
||||
2024-09-30 00:00:00+02:00,34.150001525878906,35.45000076293945,34.0,35.20000076293945,35.20000076293945,261067,0.0,0.0
|
||||
2024-10-01 00:00:00+02:00,35.20000076293945,35.88999938964844,35.18000030517578,35.61000061035156,35.61000061035156,218502,0.0,0.0
|
||||
2024-10-02 00:00:00+02:00,35.61000061035156,36.810001373291016,35.45000076293945,36.310001373291016,36.310001373291016,185328,0.0,0.0
|
||||
2024-10-03 00:00:00+02:00,36.22999954223633,36.619998931884766,36.209999084472656,36.310001373291016,36.310001373291016,246827,0.0,0.0
|
||||
2024-10-04 00:00:00+02:00,36.209999084472656,37.560001373291016,36.13999938964844,37.5099983215332,37.5099983215332,298766,0.0,0.0
|
||||
2024-10-07 00:00:00+02:00,37.5,37.5099983215332,36.47999954223633,36.91999816894531,36.91999816894531,161195,0.0,0.0
|
||||
2024-10-08 00:00:00+02:00,36.7599983215332,36.7599983215332,35.66999816894531,35.93000030517578,35.93000030517578,144993,0.0,0.0
|
||||
2024-10-09 00:00:00+02:00,35.86000061035156,36.52000045776367,35.400001525878906,36.369998931884766,36.369998931884766,123249,0.0,0.0
|
||||
2024-10-10 00:00:00+02:00,36.619998931884766,37.0,36.439998626708984,36.959999084472656,36.959999084472656,127939,0.0,0.0
|
||||
2024-10-11 00:00:00+02:00,36.650001525878906,37.349998474121094,36.560001373291016,37.150001525878906,37.150001525878906,110000,0.0,0.0
|
||||
2024-10-14 00:00:00+02:00,37.349998474121094,38.0,37.0,38.0,38.0,215775,0.0,0.0
|
||||
2024-10-15 00:00:00+02:00,38.0,38.72999954223633,37.7400016784668,38.43000030517578,38.43000030517578,289899,0.0,0.0
|
||||
2024-10-16 00:00:00+02:00,38.5,39.31999969482422,38.310001373291016,39.31999969482422,39.31999969482422,351315,0.0,0.0
|
||||
2024-10-17 00:00:00+02:00,39.27000045776367,39.310001373291016,37.95000076293945,38.439998626708984,38.439998626708984,336837,0.0,0.0
|
||||
2024-10-18 00:00:00+02:00,38.209999084472656,39.369998931884766,37.939998626708984,39.349998474121094,39.349998474121094,284589,0.0,0.0
|
||||
2024-10-21 00:00:00+02:00,39.11000061035156,39.13999938964844,38.43000030517578,39.099998474121094,39.099998474121094,176237,0.0,0.0
|
||||
2024-10-22 00:00:00+02:00,39.119998931884766,39.369998931884766,38.63999938964844,38.900001525878906,38.900001525878906,219984,0.0,0.0
|
||||
2024-10-23 00:00:00+02:00,38.70000076293945,38.86000061035156,37.790000915527344,38.79999923706055,38.79999923706055,212351,0.0,0.0
|
||||
2024-10-24 00:00:00+02:00,38.70000076293945,38.939998626708984,38.36000061035156,38.68000030517578,38.68000030517578,118090,0.0,0.0
|
||||
2024-10-25 00:00:00+02:00,38.630001068115234,38.849998474121094,38.04999923706055,38.560001373291016,38.560001373291016,164039,0.0,0.0
|
||||
2024-10-28 00:00:00+01:00,38.560001373291016,38.81999969482422,37.84000015258789,38.25,38.25,156263,0.0,0.0
|
||||
2024-10-29 00:00:00+01:00,38.25,38.88999938964844,38.029998779296875,38.31999969482422,38.31999969482422,213012,0.0,0.0
|
||||
2024-10-30 00:00:00+01:00,37.75,38.04999923706055,37.029998779296875,37.029998779296875,37.029998779296875,397551,0.0,0.0
|
||||
2024-10-31 00:00:00+01:00,37.0,37.310001373291016,36.34000015258789,37.060001373291016,37.060001373291016,281687,0.0,0.0
|
||||
2024-11-01 00:00:00+01:00,36.84000015258789,37.43000030517578,36.84000015258789,37.2400016784668,37.2400016784668,81048,0.0,0.0
|
||||
2024-11-04 00:00:00+01:00,37.060001373291016,37.79999923706055,37.040000915527344,37.560001373291016,37.560001373291016,82632,0.0,0.0
|
||||
2024-11-05 00:00:00+01:00,37.560001373291016,37.95000076293945,37.369998931884766,37.95000076293945,37.95000076293945,199518,0.0,0.0
|
||||
2024-11-06 00:00:00+01:00,38.20000076293945,38.900001525878906,34.91999816894531,34.91999816894531,34.91999816894531,469899,0.0,0.0
|
||||
2024-11-07 00:00:00+01:00,34.08000183105469,34.900001525878906,33.72999954223633,33.72999954223633,33.72999954223633,380050,0.0,0.0
|
||||
2024-11-08 00:00:00+01:00,33.61000061035156,33.91999816894531,33.29999923706055,33.54999923706055,33.54999923706055,389420,0.0,0.0
|
||||
2024-11-11 00:00:00+01:00,33.810001373291016,34.31999969482422,33.130001068115234,33.130001068115234,33.130001068115234,233145,0.0,0.0
|
||||
2024-11-12 00:00:00+01:00,32.79999923706055,33.029998779296875,31.670000076293945,31.709999084472656,31.709999084472656,284709,0.0,0.0
|
||||
2024-11-13 00:00:00+01:00,31.780000686645508,32.11000061035156,31.360000610351562,31.510000228881836,31.510000228881836,208626,0.0,0.0
|
||||
2024-11-14 00:00:00+01:00,31.600000381469727,31.8799991607666,31.34000015258789,31.40999984741211,31.40999984741211,193374,0.0,0.0
|
||||
2024-11-15 00:00:00+01:00,31.309999465942383,32.5,31.309999465942383,32.22999954223633,32.22999954223633,130866,0.0,0.0
|
||||
2024-11-18 00:00:00+01:00,32.20000076293945,32.72999954223633,32.08000183105469,32.130001068115234,32.130001068115234,94641,0.0,0.0
|
||||
2024-11-19 00:00:00+01:00,32.099998474121094,32.650001525878906,31.06999969482422,31.920000076293945,31.920000076293945,159142,0.0,0.0
|
||||
|
50
tests/test_cache.py
Normal file
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
Tests for cache
|
||||
|
||||
To run all tests in suite from commandline:
|
||||
python -m unittest tests.cache
|
||||
|
||||
Specific test class:
|
||||
python -m unittest tests.cache.TestCache
|
||||
|
||||
"""
|
||||
from tests.context import yfinance as yf
|
||||
|
||||
import unittest
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
|
||||
class TestCache(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.tempCacheDir = tempfile.TemporaryDirectory()
|
||||
yf.set_tz_cache_location(cls.tempCacheDir.name)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
yf.cache._TzDBManager.close_db()
|
||||
cls.tempCacheDir.cleanup()
|
||||
|
||||
def test_storeTzNoRaise(self):
|
||||
# storing TZ to cache should never raise exception
|
||||
tkr = 'AMZN'
|
||||
tz1 = "America/New_York"
|
||||
tz2 = "London/Europe"
|
||||
cache = yf.cache.get_tz_cache()
|
||||
cache.store(tkr, tz1)
|
||||
cache.store(tkr, tz2)
|
||||
|
||||
def test_setTzCacheLocation(self):
|
||||
self.assertEqual(yf.cache._TzDBManager.get_location(), self.tempCacheDir.name)
|
||||
|
||||
tkr = 'AMZN'
|
||||
tz1 = "America/New_York"
|
||||
cache = yf.cache.get_tz_cache()
|
||||
cache.store(tkr, tz1)
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(self.tempCacheDir.name, "tkr-tz.db")))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
52
tests/test_cache_noperms.py
Normal file
@@ -0,0 +1,52 @@
|
||||
"""
|
||||
Tests for cache
|
||||
|
||||
To run all tests in suite from commandline:
|
||||
python -m unittest tests.cache
|
||||
|
||||
Specific test class:
|
||||
python -m unittest tests.cache.TestCache
|
||||
|
||||
"""
|
||||
from tests.context import yfinance as yf
|
||||
|
||||
import unittest
|
||||
import os
|
||||
|
||||
|
||||
class TestCacheNoPermission(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if os.name == "nt": # Windows
|
||||
cls.cache_path = "C:\\Windows\\System32\\yf-cache"
|
||||
else: # Unix/Linux/MacOS
|
||||
# Use a writable directory
|
||||
cls.cache_path = "/yf-cache"
|
||||
yf.set_tz_cache_location(cls.cache_path)
|
||||
|
||||
def test_tzCacheRootStore(self):
|
||||
# Test that if cache path in read-only filesystem, no exception.
|
||||
tkr = 'AMZN'
|
||||
tz1 = "America/New_York"
|
||||
|
||||
# During attempt to store, will discover cannot write
|
||||
yf.cache.get_tz_cache().store(tkr, tz1)
|
||||
|
||||
# Handling the store failure replaces cache with a dummy
|
||||
cache = yf.cache.get_tz_cache()
|
||||
self.assertTrue(cache.dummy)
|
||||
cache.store(tkr, tz1)
|
||||
|
||||
def test_tzCacheRootLookup(self):
|
||||
# Test that if cache path in read-only filesystem, no exception.
|
||||
tkr = 'AMZN'
|
||||
# During attempt to lookup, will discover cannot write
|
||||
yf.cache.get_tz_cache().lookup(tkr)
|
||||
|
||||
# Handling the lookup failure replaces cache with a dummy
|
||||
cache = yf.cache.get_tz_cache()
|
||||
self.assertTrue(cache.dummy)
|
||||
cache.lookup(tkr)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
30
tests/test_live.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import unittest
|
||||
from unittest.mock import Mock
|
||||
|
||||
from yfinance.live import BaseWebSocket
|
||||
|
||||
|
||||
class TestWebSocket(unittest.TestCase):
|
||||
def test_decode_message_valid(self):
|
||||
message = ("CgdCVEMtVVNEFYoMuUcYwLCVgIplIgNVU0QqA0NDQzApOAFFPWrEP0iAgOrxvANVx/25R12csrRHZYD8skR9/"
|
||||
"7i0R7ABgIDq8bwD2AEE4AGAgOrxvAPoAYCA6vG8A/IBA0JUQ4ECAAAAwPrjckGJAgAA2P5ZT3tC")
|
||||
|
||||
ws = BaseWebSocket(Mock())
|
||||
decoded = ws._decode_message(message)
|
||||
|
||||
expected = {'id': 'BTC-USD', 'price': 94745.08, 'time': '1736509140000', 'currency': 'USD', 'exchange': 'CCC',
|
||||
'quote_type': 41, 'market_hours': 1, 'change_percent': 1.5344921, 'day_volume': '59712028672',
|
||||
'day_high': 95227.555, 'day_low': 92517.22, 'change': 1431.8906, 'open_price': 92529.99,
|
||||
'last_size': '59712028672', 'price_hint': '2', 'vol_24hr': '59712028672',
|
||||
'vol_all_currencies': '59712028672', 'from_currency': 'BTC', 'circulating_supply': 19808172.0,
|
||||
'market_cap': 1876726640000.0}
|
||||
|
||||
self.assertEqual(expected, decoded)
|
||||
|
||||
def test_decode_message_invalid(self):
|
||||
websocket = BaseWebSocket(Mock())
|
||||
base64_message = "invalid_base64_string"
|
||||
decoded = websocket._decode_message(base64_message)
|
||||
assert "error" in decoded
|
||||
assert "raw_base64" in decoded
|
||||
self.assertEqual(base64_message, decoded["raw_base64"])
|
||||
69
tests/test_lookup.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import unittest
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from tests.context import yfinance as yf, session_gbl
|
||||
|
||||
|
||||
class TestLookup(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.query = "A" # Generic query to make sure all lookup types are returned
|
||||
self.lookup = yf.Lookup(query=self.query, session=session_gbl)
|
||||
|
||||
def test_get_all(self):
|
||||
result = self.lookup.get_all(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_stock(self):
|
||||
result = self.lookup.get_stock(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_mutualfund(self):
|
||||
result = self.lookup.get_mutualfund(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_etf(self):
|
||||
result = self.lookup.get_etf(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_index(self):
|
||||
result = self.lookup.get_index(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_future(self):
|
||||
result = self.lookup.get_future(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_currency(self):
|
||||
result = self.lookup.get_currency(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_get_cryptocurrency(self):
|
||||
result = self.lookup.get_cryptocurrency(count=5)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 5)
|
||||
|
||||
def test_large_all(self):
|
||||
result = self.lookup.get_all(count=1000)
|
||||
|
||||
self.assertIsInstance(result, pd.DataFrame)
|
||||
self.assertEqual(len(result), 1000)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -361,15 +361,15 @@ class TestPriceRepair(unittest.TestCase):
|
||||
hist = dat._lazy_load_price_history()
|
||||
tz_exchange = dat.fast_info["timezone"]
|
||||
|
||||
df_bad = _pd.DataFrame(data={"Open": [0, 102.04, 102.04],
|
||||
"High": [0, 102.1, 102.11],
|
||||
"Low": [0, 102.04, 102.04],
|
||||
"Close": [103.03, 102.05, 102.08],
|
||||
"Adj Close": [102.03, 102.05, 102.08],
|
||||
"Volume": [560, 137, 117]},
|
||||
index=_pd.to_datetime([_dt.datetime(2022, 11, 1),
|
||||
_dt.datetime(2022, 10, 31),
|
||||
_dt.datetime(2022, 10, 30)]))
|
||||
df_bad = _pd.DataFrame(data={"Open": [0, 114.37, 114.20],
|
||||
"High": [0, 114.40, 114.40],
|
||||
"Low": [0, 114.36, 114.20],
|
||||
"Close": [114.39, 114.38, 114.45],
|
||||
"Adj Close": [114.39, 114.38, 114.45],
|
||||
"Volume": [9, 15666, 1094]},
|
||||
index=_pd.to_datetime([_dt.datetime(2025, 3, 17),
|
||||
_dt.datetime(2025, 3, 14),
|
||||
_dt.datetime(2025, 3, 13)]))
|
||||
df_bad = df_bad.sort_index()
|
||||
df_bad.index.name = "Date"
|
||||
df_bad.index = df_bad.index.tz_localize(tz_exchange)
|
||||
@@ -377,11 +377,11 @@ class TestPriceRepair(unittest.TestCase):
|
||||
repaired_df = hist._fix_zeroes(df_bad, "1d", tz_exchange, prepost=False)
|
||||
|
||||
correct_df = df_bad.copy()
|
||||
correct_df.loc["2022-11-01", "Open"] = 102.080002
|
||||
correct_df.loc["2022-11-01", "Low"] = 102.032501
|
||||
correct_df.loc["2022-11-01", "High"] = 102.080002
|
||||
correct_df.loc["2025-03-17", "Open"] = 114.62
|
||||
correct_df.loc["2025-03-17", "High"] = 114.62
|
||||
correct_df.loc["2025-03-17", "Low"] = 114.41
|
||||
for c in ["Open", "Low", "High", "Close"]:
|
||||
self.assertTrue(_np.isclose(repaired_df[c], correct_df[c], rtol=1e-8).all())
|
||||
self.assertTrue(_np.isclose(repaired_df[c], correct_df[c], rtol=1e-7).all())
|
||||
|
||||
self.assertTrue("Repaired?" in repaired_df.columns)
|
||||
self.assertFalse(repaired_df["Repaired?"].isna().any())
|
||||
@@ -390,19 +390,21 @@ class TestPriceRepair(unittest.TestCase):
|
||||
# Test that 'Adj Close' is reconstructed correctly,
|
||||
# particularly when a dividend occurred within 1 day.
|
||||
|
||||
self.skipTest("Currently failing because Yahoo returning slightly different data for interval 1d vs 1h on day Aug 6 2024")
|
||||
|
||||
tkr = "INTC"
|
||||
df = _pd.DataFrame(data={"Open": [28.95, 28.65, 29.55, 29.62, 29.25],
|
||||
"High": [29.12, 29.27, 29.65, 31.17, 30.30],
|
||||
"Low": [28.21, 28.43, 28.61, 29.53, 28.80],
|
||||
"Close": [28.24, 29.05, 28.69, 30.32, 30.19],
|
||||
"Adj Close": [28.12, 28.93, 28.57, 29.83, 29.70],
|
||||
"Volume": [36e6, 51e6, 49e6, 58e6, 62e6],
|
||||
"Dividends": [0, 0, 0.365, 0, 0]},
|
||||
index=_pd.to_datetime([_dt.datetime(2023, 2, 8),
|
||||
_dt.datetime(2023, 2, 7),
|
||||
_dt.datetime(2023, 2, 6),
|
||||
_dt.datetime(2023, 2, 3),
|
||||
_dt.datetime(2023, 2, 2)]))
|
||||
df = _pd.DataFrame(data={"Open": [2.020000e+01, 2.032000e+01, 1.992000e+01, 1.910000e+01, 2.008000e+01],
|
||||
"High": [2.039000e+01, 2.063000e+01, 2.025000e+01, 2.055000e+01, 2.015000e+01],
|
||||
"Low": [1.929000e+01, 1.975000e+01, 1.895000e+01, 1.884000e+01, 1.950000e+01],
|
||||
"Close": [2.011000e+01, 1.983000e+01, 1.899000e+01, 2.049000e+01, 1.971000e+01],
|
||||
"Adj Close": [1.998323e+01, 1.970500e+01, 1.899000e+01, 2.049000e+01, 1.971000e+01],
|
||||
"Volume": [1.473857e+08, 1.066704e+08, 9.797230e+07, 9.683680e+07, 7.639450e+07],
|
||||
"Dividends": [0.000000e+00, 0.000000e+00, 1.250000e-01, 0.000000e+00, 0.000000e+00]},
|
||||
index=_pd.to_datetime([_dt.datetime(2024, 8, 9),
|
||||
_dt.datetime(2024, 8, 8),
|
||||
_dt.datetime(2024, 8, 7),
|
||||
_dt.datetime(2024, 8, 6),
|
||||
_dt.datetime(2024, 8, 5)]))
|
||||
df = df.sort_index()
|
||||
df.index.name = "Date"
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
@@ -462,7 +464,7 @@ class TestPriceRepair(unittest.TestCase):
|
||||
# Stocks that split in 2022 but no problems in Yahoo data,
|
||||
# so repair should change nothing
|
||||
good_tkrs = ['AMZN', 'DXCM', 'FTNT', 'GOOG', 'GME', 'PANW', 'SHOP', 'TSLA']
|
||||
good_tkrs += ['AEI', 'GHI', 'IRON', 'LXU', 'NUZE', 'RSLS', 'TISI']
|
||||
good_tkrs += ['AEI', 'GHI', 'IRON', 'LXU', 'RSLS', 'TISI']
|
||||
good_tkrs += ['BOL.ST', 'TUI1.DE']
|
||||
intervals = ['1d', '1wk', '1mo', '3mo']
|
||||
for tkr in good_tkrs:
|
||||
@@ -488,7 +490,7 @@ class TestPriceRepair(unittest.TestCase):
|
||||
print(df_dbg[f_diff | _np.roll(f_diff, 1) | _np.roll(f_diff, -1)])
|
||||
raise
|
||||
|
||||
bad_tkrs = ['4063.T', 'ALPHA.PA', 'AV.L', 'CNE.L', 'MOB.ST', 'SPM.MI']
|
||||
bad_tkrs = ['4063.T', 'AV.L', 'CNE.L', 'MOB.ST', 'SPM.MI']
|
||||
bad_tkrs.append('LA.V') # special case - stock split error is 3 years ago! why not fixed?
|
||||
for tkr in bad_tkrs:
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
@@ -580,7 +582,6 @@ class TestPriceRepair(unittest.TestCase):
|
||||
# Div 100x
|
||||
bad_tkrs += ['ABDP.L']
|
||||
bad_tkrs += ['ELCO.L']
|
||||
bad_tkrs += ['KWS.L']
|
||||
bad_tkrs += ['PSH.L']
|
||||
|
||||
# Div 100x and adjust too big
|
||||
@@ -598,7 +599,6 @@ class TestPriceRepair(unittest.TestCase):
|
||||
# Phantom divs
|
||||
bad_tkrs += ['KAP.IL'] # 1x 1d phantom div, and false positives 0.01x in 1wk
|
||||
bad_tkrs += ['SAND']
|
||||
bad_tkrs += ['SOLB.BR'] # 1x phantom div, but some false-positive 100x. and had to improve phantom detection
|
||||
bad_tkrs += ['TEM.L']
|
||||
bad_tkrs += ['TEP.PA']
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
|
||||
def test_download_multi_small_interval(self):
|
||||
use_tkrs = ["AAPL", "0Q3.DE", "ATVI"]
|
||||
df = yf.download(use_tkrs, period="1d", interval="5m")
|
||||
df = yf.download(use_tkrs, period="1d", interval="5m", auto_adjust=True)
|
||||
self.assertEqual(df.index.tz, _dt.timezone.utc)
|
||||
|
||||
def test_download_with_invalid_ticker(self):
|
||||
@@ -56,16 +56,17 @@ class TestPriceHistory(unittest.TestCase):
|
||||
invalid_tkrs = ["AAPL", "ATVI"] #AAPL exists and ATVI does not exist
|
||||
valid_tkrs = ["AAPL", "INTC"] #AAPL and INTC both exist
|
||||
|
||||
data_invalid_sym = yf.download(invalid_tkrs, start='2023-11-16', end='2023-11-17')
|
||||
data_valid_sym = yf.download(valid_tkrs, start='2023-11-16', end='2023-11-17')
|
||||
|
||||
self.assertEqual(data_invalid_sym['Close']['AAPL']['2023-11-16'],data_valid_sym['Close']['AAPL']['2023-11-16'])
|
||||
start_d = _dt.date.today() - _dt.timedelta(days=30)
|
||||
data_invalid_sym = yf.download(invalid_tkrs, start=start_d, auto_adjust=True)
|
||||
data_valid_sym = yf.download(valid_tkrs, start=start_d, auto_adjust=True)
|
||||
dt_compare = data_valid_sym.index[0]
|
||||
self.assertEqual(data_invalid_sym['Close']['AAPL'][dt_compare],data_valid_sym['Close']['AAPL'][dt_compare])
|
||||
|
||||
def test_duplicatingHourly(self):
|
||||
tkrs = ["IMP.JO", "BHG.JO", "SSW.JO", "BP.L", "INTC"]
|
||||
for tkr in tkrs:
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
tz = dat._get_ticker_tz(proxy=None, timeout=None)
|
||||
tz = dat._get_ticker_tz(timeout=None)
|
||||
|
||||
dt_utc = _pd.Timestamp.utcnow()
|
||||
dt = dt_utc.astimezone(_tz.timezone(tz))
|
||||
@@ -85,7 +86,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
test_run = False
|
||||
for tkr in tkrs:
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
tz = dat._get_ticker_tz(proxy=None, timeout=None)
|
||||
tz = dat._get_ticker_tz(timeout=None)
|
||||
|
||||
dt_utc = _pd.Timestamp.utcnow()
|
||||
dt = dt_utc.astimezone(_tz.timezone(tz))
|
||||
@@ -111,7 +112,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
test_run = False
|
||||
for tkr in tkrs:
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
tz = dat._get_ticker_tz(proxy=None, timeout=None)
|
||||
tz = dat._get_ticker_tz(timeout=None)
|
||||
|
||||
dt = _tz.timezone(tz).localize(_dt.datetime.now())
|
||||
if dt.date().weekday() not in [1, 2, 3, 4]:
|
||||
@@ -185,7 +186,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
|
||||
df_intraday_divs = df_intraday["Dividends"][df_intraday["Dividends"] != 0]
|
||||
df_intraday_divs.index = df_intraday_divs.index.floor('D')
|
||||
self.assertTrue(df_daily_divs.equals(df_intraday_divs))
|
||||
self.assertTrue(df_daily_divs.index.equals(df_intraday_divs.index))
|
||||
|
||||
test_run = True
|
||||
|
||||
@@ -212,7 +213,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
|
||||
df_intraday_divs = df_intraday["Dividends"][df_intraday["Dividends"] != 0]
|
||||
df_intraday_divs.index = df_intraday_divs.index.floor('D')
|
||||
self.assertTrue(df_daily_divs.equals(df_intraday_divs))
|
||||
self.assertTrue(df_daily_divs.index.equals(df_intraday_divs.index))
|
||||
|
||||
test_run = True
|
||||
|
||||
@@ -223,7 +224,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
start_d = _dt.date(2022, 1, 1)
|
||||
end_d = _dt.date(2023, 1, 1)
|
||||
|
||||
tkr_div_dates = {'BHP.AX': [_dt.date(2022, 9, 1), _dt.date(2022, 2, 24)], # Yahoo claims 23-Feb but wrong because DST
|
||||
tkr_div_dates = {'BHP.AX': [_dt.date(2022, 9, 1), _dt.date(2022, 2, 24)],
|
||||
'IMP.JO': [_dt.date(2022, 9, 21), _dt.date(2022, 3, 16)],
|
||||
'BP.L': [_dt.date(2022, 11, 10), _dt.date(2022, 8, 11), _dt.date(2022, 5, 12),
|
||||
_dt.date(2022, 2, 17)],
|
||||
@@ -401,7 +402,7 @@ class TestPriceHistory(unittest.TestCase):
|
||||
|
||||
# Setup
|
||||
tkr = "AMZN"
|
||||
special_day = _dt.date(2023, 11, 24)
|
||||
special_day = _dt.date(2024, 11, 29)
|
||||
time_early_close = _dt.time(13)
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
|
||||
@@ -416,6 +417,8 @@ class TestPriceHistory(unittest.TestCase):
|
||||
start_d = _dt.date(special_day.year, 1, 1)
|
||||
end_d = _dt.date(special_day.year+1, 1, 1)
|
||||
df = dat.history(start=start_d, end=end_d, interval="1h", prepost=False, keepna=True)
|
||||
if df.empty:
|
||||
self.skipTest("TEST NEEDS UPDATE: 'special_day' needs to be LATEST Thanksgiving date")
|
||||
last_dts = _pd.Series(df.index).groupby(df.index.date).last()
|
||||
dfd = dat.history(start=start_d, end=end_d, interval='1d', prepost=False, keepna=True)
|
||||
self.assertTrue(_np.equal(dfd.index.date, _pd.to_datetime(last_dts.index).date).all())
|
||||
@@ -423,12 +426,12 @@ class TestPriceHistory(unittest.TestCase):
|
||||
def test_prune_post_intraday_asx(self):
|
||||
# Setup
|
||||
tkr = "BHP.AX"
|
||||
# No early closes in 2023
|
||||
# No early closes in 2024
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
|
||||
# Test no other afternoons (or mornings) were pruned
|
||||
start_d = _dt.date(2023, 1, 1)
|
||||
end_d = _dt.date(2023+1, 1, 1)
|
||||
start_d = _dt.date(2024, 1, 1)
|
||||
end_d = _dt.date(2024+1, 1, 1)
|
||||
df = dat.history(start=start_d, end=end_d, interval="1h", prepost=False, keepna=True)
|
||||
last_dts = _pd.Series(df.index).groupby(df.index.date).last()
|
||||
dfd = dat.history(start=start_d, end=end_d, interval='1d', prepost=False, keepna=True)
|
||||
|
||||
@@ -18,9 +18,9 @@ from yfinance.exceptions import YFPricesMissingError, YFInvalidPeriodError, YFNo
|
||||
|
||||
|
||||
import unittest
|
||||
import requests_cache
|
||||
# import requests_cache
|
||||
from typing import Union, Any, get_args, _GenericAlias
|
||||
from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
|
||||
# from urllib.parse import urlparse, parse_qs, urlencode, urlunparse
|
||||
|
||||
ticker_attributes = (
|
||||
("major_holders", pd.DataFrame),
|
||||
@@ -37,10 +37,12 @@ ticker_attributes = (
|
||||
("recommendations", Union[pd.DataFrame, dict]),
|
||||
("recommendations_summary", Union[pd.DataFrame, dict]),
|
||||
("upgrades_downgrades", Union[pd.DataFrame, dict]),
|
||||
("ttm_cashflow", pd.DataFrame),
|
||||
("quarterly_cashflow", pd.DataFrame),
|
||||
("cashflow", pd.DataFrame),
|
||||
("quarterly_balance_sheet", pd.DataFrame),
|
||||
("balance_sheet", pd.DataFrame),
|
||||
("ttm_income_stmt", pd.DataFrame),
|
||||
("quarterly_income_stmt", pd.DataFrame),
|
||||
("income_stmt", pd.DataFrame),
|
||||
("analyst_price_targets", dict),
|
||||
@@ -78,8 +80,6 @@ class TestTicker(unittest.TestCase):
|
||||
def setUpClass(cls):
|
||||
cls.session = session_gbl
|
||||
|
||||
cls.proxy = None
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
if cls.session is not None:
|
||||
@@ -93,7 +93,7 @@ class TestTicker(unittest.TestCase):
|
||||
|
||||
# Test:
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
tz = dat._get_ticker_tz(proxy=None, timeout=5)
|
||||
tz = dat._get_ticker_tz(timeout=5)
|
||||
|
||||
self.assertIsNotNone(tz)
|
||||
|
||||
@@ -180,7 +180,7 @@ class TestTicker(unittest.TestCase):
|
||||
expected_start = expected_start.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
|
||||
# leeway added because of weekends
|
||||
self.assertGreaterEqual(actual_start, expected_start - timedelta(days=7),
|
||||
self.assertGreaterEqual(actual_start, expected_start - timedelta(days=10),
|
||||
f"Start date {actual_start} out of range for period={period}")
|
||||
self.assertLessEqual(df.index[-1].to_pydatetime().replace(tzinfo=None), now,
|
||||
f"End date {df.index[-1]} out of range for period={period}")
|
||||
@@ -225,10 +225,10 @@ class TestTicker(unittest.TestCase):
|
||||
|
||||
def test_goodTicker_withProxy(self):
|
||||
tkr = "IBM"
|
||||
dat = yf.Ticker(tkr, session=self.session, proxy=self.proxy)
|
||||
dat = yf.Ticker(tkr, session=self.session)
|
||||
|
||||
dat._fetch_ticker_tz(proxy=None, timeout=5)
|
||||
dat._get_ticker_tz(proxy=None, timeout=5)
|
||||
dat._fetch_ticker_tz(timeout=5)
|
||||
dat._get_ticker_tz(timeout=5)
|
||||
dat.history(period="5d")
|
||||
|
||||
for attribute_name, attribute_type in ticker_attributes:
|
||||
@@ -284,38 +284,38 @@ class TestTickerHistory(unittest.TestCase):
|
||||
else:
|
||||
self.assertIsInstance(data.columns, pd.MultiIndex)
|
||||
|
||||
def test_no_expensive_calls_introduced(self):
|
||||
"""
|
||||
Make sure calling history to get price data has not introduced more calls to yahoo than absolutely necessary.
|
||||
As doing other type of scraping calls than "query2.finance.yahoo.com/v8/finance/chart" to yahoo website
|
||||
will quickly trigger spam-block when doing bulk download of history data.
|
||||
"""
|
||||
symbol = "GOOGL"
|
||||
period = "1y"
|
||||
with requests_cache.CachedSession(backend="memory") as session:
|
||||
ticker = yf.Ticker(symbol, session=session)
|
||||
ticker.history(period=period)
|
||||
actual_urls_called = [r.url for r in session.cache.filter()]
|
||||
# Hopefully one day we find an equivalent "requests_cache" that works with "curl_cffi"
|
||||
# def test_no_expensive_calls_introduced(self):
|
||||
# """
|
||||
# Make sure calling history to get price data has not introduced more calls to yahoo than absolutely necessary.
|
||||
# As doing other type of scraping calls than "query2.finance.yahoo.com/v8/finance/chart" to yahoo website
|
||||
# will quickly trigger spam-block when doing bulk download of history data.
|
||||
# """
|
||||
# symbol = "GOOGL"
|
||||
# period = "1y"
|
||||
# with requests_cache.CachedSession(backend="memory") as session:
|
||||
# ticker = yf.Ticker(symbol, session=session)
|
||||
# ticker.history(period=period)
|
||||
# actual_urls_called = [r.url for r in session.cache.filter()]
|
||||
|
||||
# Remove 'crumb' argument
|
||||
for i in range(len(actual_urls_called)):
|
||||
u = actual_urls_called[i]
|
||||
parsed_url = urlparse(u)
|
||||
query_params = parse_qs(parsed_url.query)
|
||||
query_params.pop('crumb', None)
|
||||
query_params.pop('cookie', None)
|
||||
u = urlunparse(parsed_url._replace(query=urlencode(query_params, doseq=True)))
|
||||
actual_urls_called[i] = u
|
||||
actual_urls_called = tuple(actual_urls_called)
|
||||
# # Remove 'crumb' argument
|
||||
# for i in range(len(actual_urls_called)):
|
||||
# u = actual_urls_called[i]
|
||||
# parsed_url = urlparse(u)
|
||||
# query_params = parse_qs(parsed_url.query)
|
||||
# query_params.pop('crumb', None)
|
||||
# query_params.pop('cookie', None)
|
||||
# u = urlunparse(parsed_url._replace(query=urlencode(query_params, doseq=True)))
|
||||
# actual_urls_called[i] = u
|
||||
# actual_urls_called = tuple(actual_urls_called)
|
||||
|
||||
# expected_urls = [
|
||||
# f"https://query2.finance.yahoo.com/v8/finance/chart/{symbol}?interval=1d&range=1d", # ticker's tz
|
||||
# f"https://query2.finance.yahoo.com/v8/finance/chart/{symbol}?events=div%2Csplits%2CcapitalGains&includePrePost=False&interval=1d&range={period}"
|
||||
# ]
|
||||
# for url in actual_urls_called:
|
||||
# self.assertTrue(url in expected_urls, f"Unexpected URL called: {url}")
|
||||
|
||||
expected_urls = (
|
||||
f"https://query2.finance.yahoo.com/v8/finance/chart/{symbol}?events=div%2Csplits%2CcapitalGains&includePrePost=False&interval=1d&range={period}",
|
||||
)
|
||||
self.assertEqual(
|
||||
expected_urls,
|
||||
actual_urls_called,
|
||||
"Different than expected url used to fetch history."
|
||||
)
|
||||
def test_dividends(self):
|
||||
data = self.ticker.dividends
|
||||
self.assertIsInstance(data, pd.Series, "data has wrong type")
|
||||
@@ -331,6 +331,12 @@ class TestTickerHistory(unittest.TestCase):
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
def test_chained_history_calls(self):
|
||||
_ = self.ticker.history(period="2d")
|
||||
data = self.ticker.dividends
|
||||
self.assertIsInstance(data, pd.Series, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
|
||||
class TestTickerEarnings(unittest.TestCase):
|
||||
session = None
|
||||
@@ -358,7 +364,7 @@ class TestTickerEarnings(unittest.TestCase):
|
||||
def test_earnings_dates_with_limit(self):
|
||||
# use ticker with lots of historic earnings
|
||||
ticker = yf.Ticker("IBM")
|
||||
limit = 110
|
||||
limit = 100
|
||||
data = ticker.get_earnings_dates(limit=limit)
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
@@ -555,6 +561,34 @@ class TestTickerMiscFinancials(unittest.TestCase):
|
||||
data = self.ticker.get_income_stmt(as_dict=True)
|
||||
self.assertIsInstance(data, dict, "data has wrong type")
|
||||
|
||||
def test_ttm_income_statement(self):
|
||||
expected_keys = ["Total Revenue", "Pretax Income", "Normalized EBITDA"]
|
||||
|
||||
# Test contents of table
|
||||
data = self.ticker.get_income_stmt(pretty=True, freq='trailing')
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
for k in expected_keys:
|
||||
self.assertIn(k, data.index, "Did not find expected row in index")
|
||||
# Trailing 12 months there must be exactly one column
|
||||
self.assertEqual(len(data.columns), 1, "Only one column should be returned on TTM income statement")
|
||||
|
||||
# Test property defaults
|
||||
data2 = self.ticker.ttm_income_stmt
|
||||
self.assertTrue(data.equals(data2), "property not defaulting to 'pretty=True'")
|
||||
|
||||
# Test pretty=False
|
||||
expected_keys = [k.replace(' ', '') for k in expected_keys]
|
||||
data = self.ticker.get_income_stmt(pretty=False, freq='trailing')
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
for k in expected_keys:
|
||||
self.assertIn(k, data.index, "Did not find expected row in index")
|
||||
|
||||
# Test to_dict
|
||||
data = self.ticker.get_income_stmt(as_dict=True, freq='trailing')
|
||||
self.assertIsInstance(data, dict, "data has wrong type")
|
||||
|
||||
def test_balance_sheet(self):
|
||||
expected_keys = ["Total Assets", "Net PPE"]
|
||||
expected_periods_days = 365
|
||||
@@ -671,6 +705,34 @@ class TestTickerMiscFinancials(unittest.TestCase):
|
||||
data = self.ticker.get_cashflow(as_dict=True)
|
||||
self.assertIsInstance(data, dict, "data has wrong type")
|
||||
|
||||
def test_ttm_cash_flow(self):
|
||||
expected_keys = ["Operating Cash Flow", "Net PPE Purchase And Sale"]
|
||||
|
||||
# Test contents of table
|
||||
data = self.ticker.get_cashflow(pretty=True, freq='trailing')
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
for k in expected_keys:
|
||||
self.assertIn(k, data.index, "Did not find expected row in index")
|
||||
# Trailing 12 months there must be exactly one column
|
||||
self.assertEqual(len(data.columns), 1, "Only one column should be returned on TTM cash flow")
|
||||
|
||||
# Test property defaults
|
||||
data2 = self.ticker.ttm_cashflow
|
||||
self.assertTrue(data.equals(data2), "property not defaulting to 'pretty=True'")
|
||||
|
||||
# Test pretty=False
|
||||
expected_keys = [k.replace(' ', '') for k in expected_keys]
|
||||
data = self.ticker.get_cashflow(pretty=False, freq='trailing')
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
for k in expected_keys:
|
||||
self.assertIn(k, data.index, "Did not find expected row in index")
|
||||
|
||||
# Test to_dict
|
||||
data = self.ticker.get_cashflow(as_dict=True, freq='trailing')
|
||||
self.assertIsInstance(data, dict, "data has wrong type")
|
||||
|
||||
def test_income_alt_names(self):
|
||||
i1 = self.ticker.income_stmt
|
||||
i2 = self.ticker.incomestmt
|
||||
@@ -696,6 +758,18 @@ class TestTickerMiscFinancials(unittest.TestCase):
|
||||
i3 = self.ticker.get_financials(freq="quarterly")
|
||||
self.assertTrue(i1.equals(i3))
|
||||
|
||||
i1 = self.ticker.ttm_income_stmt
|
||||
i2 = self.ticker.ttm_incomestmt
|
||||
self.assertTrue(i1.equals(i2))
|
||||
i3 = self.ticker.ttm_financials
|
||||
self.assertTrue(i1.equals(i3))
|
||||
|
||||
i1 = self.ticker.get_income_stmt(freq="trailing")
|
||||
i2 = self.ticker.get_incomestmt(freq="trailing")
|
||||
self.assertTrue(i1.equals(i2))
|
||||
i3 = self.ticker.get_financials(freq="trailing")
|
||||
self.assertTrue(i1.equals(i3))
|
||||
|
||||
def test_balance_sheet_alt_names(self):
|
||||
i1 = self.ticker.balance_sheet
|
||||
i2 = self.ticker.balancesheet
|
||||
@@ -730,6 +804,14 @@ class TestTickerMiscFinancials(unittest.TestCase):
|
||||
i2 = self.ticker.get_cashflow(freq="quarterly")
|
||||
self.assertTrue(i1.equals(i2))
|
||||
|
||||
i1 = self.ticker.ttm_cash_flow
|
||||
i2 = self.ticker.ttm_cashflow
|
||||
self.assertTrue(i1.equals(i2))
|
||||
|
||||
i1 = self.ticker.get_cash_flow(freq="trailing")
|
||||
i2 = self.ticker.get_cashflow(freq="trailing")
|
||||
self.assertTrue(i1.equals(i2))
|
||||
|
||||
def test_bad_freq_value_raises_exception(self):
|
||||
self.assertRaises(ValueError, lambda: self.ticker.get_cashflow(freq="badarg"))
|
||||
|
||||
@@ -808,8 +890,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
data = self.ticker.upgrades_downgrades
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
self.assertTrue(len(data.columns) == 4, "data has wrong number of columns")
|
||||
self.assertCountEqual(data.columns.values.tolist(), ['Firm', 'ToGrade', 'FromGrade', 'Action'], "data has wrong column names")
|
||||
self.assertIsInstance(data.index, pd.DatetimeIndex, "data has wrong index type")
|
||||
|
||||
data_cached = self.ticker.upgrades_downgrades
|
||||
@@ -819,9 +899,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
data = self.ticker.analyst_price_targets
|
||||
self.assertIsInstance(data, dict, "data has wrong type")
|
||||
|
||||
keys = {'current', 'low', 'high', 'mean', 'median'}
|
||||
self.assertCountEqual(data.keys(), keys, "data has wrong keys")
|
||||
|
||||
data_cached = self.ticker.analyst_price_targets
|
||||
self.assertIs(data, data_cached, "data not cached")
|
||||
|
||||
@@ -830,12 +907,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
columns = ['numberOfAnalysts', 'avg', 'low', 'high', 'yearAgoEps', 'growth']
|
||||
self.assertCountEqual(data.columns.values.tolist(), columns, "data has wrong column names")
|
||||
|
||||
index = ['0q', '+1q', '0y', '+1y']
|
||||
self.assertCountEqual(data.index.values.tolist(), index, "data has wrong row names")
|
||||
|
||||
data_cached = self.ticker.earnings_estimate
|
||||
self.assertIs(data, data_cached, "data not cached")
|
||||
|
||||
@@ -844,12 +915,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
columns = ['numberOfAnalysts', 'avg', 'low', 'high', 'yearAgoRevenue', 'growth']
|
||||
self.assertCountEqual(data.columns.values.tolist(), columns, "data has wrong column names")
|
||||
|
||||
index = ['0q', '+1q', '0y', '+1y']
|
||||
self.assertCountEqual(data.index.values.tolist(), index, "data has wrong row names")
|
||||
|
||||
data_cached = self.ticker.revenue_estimate
|
||||
self.assertIs(data, data_cached, "data not cached")
|
||||
|
||||
@@ -858,8 +923,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
columns = ['epsEstimate', 'epsActual', 'epsDifference', 'surprisePercent']
|
||||
self.assertCountEqual(data.columns.values.tolist(), columns, "data has wrong column names")
|
||||
self.assertIsInstance(data.index, pd.DatetimeIndex, "data has wrong index type")
|
||||
|
||||
data_cached = self.ticker.earnings_history
|
||||
@@ -870,12 +933,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
columns = ['current', '7daysAgo', '30daysAgo', '60daysAgo', '90daysAgo']
|
||||
self.assertCountEqual(data.columns.values.tolist(), columns, "data has wrong column names")
|
||||
|
||||
index = ['0q', '+1q', '0y', '+1y']
|
||||
self.assertCountEqual(data.index.values.tolist(), index, "data has wrong row names")
|
||||
|
||||
data_cached = self.ticker.eps_trend
|
||||
self.assertIs(data, data_cached, "data not cached")
|
||||
|
||||
@@ -884,12 +941,6 @@ class TestTickerAnalysts(unittest.TestCase):
|
||||
self.assertIsInstance(data, pd.DataFrame, "data has wrong type")
|
||||
self.assertFalse(data.empty, "data is empty")
|
||||
|
||||
columns = ['stockTrend', 'indexTrend']
|
||||
self.assertCountEqual(data.columns.values.tolist(), columns, "data has wrong column names")
|
||||
|
||||
index = ['0q', '+1q', '0y', '+1y', '+5y']
|
||||
self.assertCountEqual(data.index.values.tolist(), index, "data has wrong row names")
|
||||
|
||||
data_cached = self.ticker.growth_estimates
|
||||
self.assertIs(data, data_cached, "data not cached")
|
||||
|
||||
@@ -932,6 +983,7 @@ class TestTickerInfo(unittest.TestCase):
|
||||
self.symbols.append("QCSTIX") # good for testing, doesn't trade
|
||||
self.symbols += ["BTC-USD", "IWO", "VFINX", "^GSPC"]
|
||||
self.symbols += ["SOKE.IS", "ADS.DE"] # detected bugs
|
||||
self.symbols += ["EXTO", "NEPT" ] # Issues 2343 and 2363
|
||||
self.tickers = [yf.Ticker(s, session=self.session) for s in self.symbols]
|
||||
|
||||
def tearDown(self):
|
||||
@@ -947,7 +999,6 @@ class TestTickerInfo(unittest.TestCase):
|
||||
self.assertIsInstance(data, dict, "data has wrong type")
|
||||
expected_keys = ['industry', 'currentPrice', 'exchange', 'floatShares', 'companyOfficers', 'bid']
|
||||
for k in expected_keys:
|
||||
print(k)
|
||||
self.assertIn("symbol", data.keys(), f"Did not find expected key '{k}' in info dict")
|
||||
self.assertEqual(self.symbols[0], data["symbol"], "Wrong symbol value in info dict")
|
||||
|
||||
@@ -962,6 +1013,37 @@ class TestTickerInfo(unittest.TestCase):
|
||||
data2 = self.tickers[2].info
|
||||
self.assertIsInstance(data2['trailingPegRatio'], float)
|
||||
|
||||
def test_isin_info(self):
|
||||
isin_list = {"ES0137650018": True,
|
||||
"does_not_exist": True, # Nonexistent but doesn't raise an error
|
||||
"INF209K01EN2": True,
|
||||
"INX846K01K35": False, # Nonexistent and raises an error
|
||||
"INF846K01K35": True
|
||||
}
|
||||
for isin in isin_list:
|
||||
if not isin_list[isin]:
|
||||
with self.assertRaises(ValueError) as context:
|
||||
ticker = yf.Ticker(isin)
|
||||
self.assertIn(str(context.exception), [ f"Invalid ISIN number: {isin}", "Empty tickername" ])
|
||||
else:
|
||||
ticker = yf.Ticker(isin)
|
||||
ticker.info
|
||||
|
||||
def test_empty_info(self):
|
||||
# Test issue 2343 (Empty result _fetch)
|
||||
data = self.tickers[10].info
|
||||
self.assertCountEqual(['quoteType', 'symbol', 'underlyingSymbol', 'uuid', 'maxAge', 'trailingPegRatio'], data.keys())
|
||||
self.assertIn("trailingPegRatio", data.keys(), "Did not find expected key 'trailingPegRatio' in info dict")
|
||||
|
||||
# Test issue 2363 (Empty QuoteResponse)
|
||||
data = self.tickers[11].info
|
||||
expected_keys = ['maxAge', 'priceHint', 'previousClose', 'open', 'dayLow', 'dayHigh', 'regularMarketPreviousClose',
|
||||
'regularMarketOpen', 'regularMarketDayLow', 'regularMarketDayHigh', 'volume', 'regularMarketVolume',
|
||||
'bid', 'ask', 'bidSize', 'askSize', 'fiftyTwoWeekLow', 'fiftyTwoWeekHigh', 'currency', 'tradeable',
|
||||
'exchange', 'quoteType', 'symbol', 'underlyingSymbol', 'shortName', 'timeZoneFullName', 'timeZoneShortName',
|
||||
'uuid', 'gmtOffSetMilliseconds', 'trailingPegRatio']
|
||||
self.assertCountEqual(expected_keys, data.keys())
|
||||
|
||||
# def test_fast_info_matches_info(self):
|
||||
# fast_info_keys = set()
|
||||
# for ticker in self.tickers:
|
||||
|
||||
@@ -12,76 +12,10 @@ from datetime import datetime
|
||||
from unittest import TestSuite
|
||||
|
||||
import pandas as pd
|
||||
# import numpy as np
|
||||
|
||||
from tests.context import yfinance as yf
|
||||
|
||||
import unittest
|
||||
# import requests_cache
|
||||
import tempfile
|
||||
import os
|
||||
|
||||
from yfinance.utils import is_valid_period_format
|
||||
|
||||
|
||||
class TestCache(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.tempCacheDir = tempfile.TemporaryDirectory()
|
||||
yf.set_tz_cache_location(cls.tempCacheDir.name)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls.tempCacheDir.cleanup()
|
||||
|
||||
def test_storeTzNoRaise(self):
|
||||
# storing TZ to cache should never raise exception
|
||||
tkr = 'AMZN'
|
||||
tz1 = "America/New_York"
|
||||
tz2 = "London/Europe"
|
||||
cache = yf.cache.get_tz_cache()
|
||||
cache.store(tkr, tz1)
|
||||
cache.store(tkr, tz2)
|
||||
|
||||
def test_setTzCacheLocation(self):
|
||||
self.assertEqual(yf.cache._TzDBManager.get_location(), self.tempCacheDir.name)
|
||||
|
||||
tkr = 'AMZN'
|
||||
tz1 = "America/New_York"
|
||||
cache = yf.cache.get_tz_cache()
|
||||
cache.store(tkr, tz1)
|
||||
|
||||
self.assertTrue(os.path.exists(os.path.join(self.tempCacheDir.name, "tkr-tz.db")))
|
||||
|
||||
|
||||
class TestCacheNoPermission(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
yf.set_tz_cache_location("/root/yf-cache")
|
||||
|
||||
def test_tzCacheRootStore(self):
|
||||
# Test that if cache path in read-only filesystem, no exception.
|
||||
tkr = 'AMZN'
|
||||
tz1 = "America/New_York"
|
||||
|
||||
# During attempt to store, will discover cannot write
|
||||
yf.cache.get_tz_cache().store(tkr, tz1)
|
||||
|
||||
# Handling the store failure replaces cache with a dummy
|
||||
cache = yf.cache.get_tz_cache()
|
||||
self.assertTrue(cache.dummy)
|
||||
cache.store(tkr, tz1)
|
||||
|
||||
def test_tzCacheRootLookup(self):
|
||||
# Test that if cache path in read-only filesystem, no exception.
|
||||
tkr = 'AMZN'
|
||||
# During attempt to lookup, will discover cannot write
|
||||
yf.cache.get_tz_cache().lookup(tkr)
|
||||
|
||||
# Handling the lookup failure replaces cache with a dummy
|
||||
cache = yf.cache.get_tz_cache()
|
||||
self.assertTrue(cache.dummy)
|
||||
cache.lookup(tkr)
|
||||
from yfinance.utils import is_valid_period_format, _dts_in_same_interval
|
||||
|
||||
|
||||
class TestPandas(unittest.TestCase):
|
||||
@@ -127,10 +61,120 @@ class TestUtils(unittest.TestCase):
|
||||
self.assertTrue(is_valid_period_format("999mo")) # Large number valid
|
||||
|
||||
|
||||
class TestDateIntervalCheck(unittest.TestCase):
|
||||
def test_same_day(self):
|
||||
dt1 = pd.Timestamp("2024-10-15 10:00:00")
|
||||
dt2 = pd.Timestamp("2024-10-15 14:30:00")
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "1d"))
|
||||
|
||||
def test_different_days(self):
|
||||
dt1 = pd.Timestamp("2024-10-15 10:00:00")
|
||||
dt2 = pd.Timestamp("2024-10-16 09:00:00")
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt2, "1d"))
|
||||
|
||||
def test_same_week_mid_week(self):
|
||||
# Wednesday and Friday in same week
|
||||
dt1 = pd.Timestamp("2024-10-16") # Wednesday
|
||||
dt2 = pd.Timestamp("2024-10-18") # Friday
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "1wk"))
|
||||
|
||||
def test_different_weeks(self):
|
||||
dt1 = pd.Timestamp("2024-10-14") # Monday week 42
|
||||
dt2 = pd.Timestamp("2024-10-21") # Monday week 43
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt2, "1wk"))
|
||||
|
||||
def test_week_year_boundary(self):
|
||||
# Week 52 of 2024 spans into 2025
|
||||
dt1 = pd.Timestamp("2024-12-30") # Monday in week 1 (ISO calendar)
|
||||
dt2 = pd.Timestamp("2025-01-03") # Friday in week 1 (ISO calendar)
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "1wk"))
|
||||
|
||||
def test_same_month(self):
|
||||
dt1 = pd.Timestamp("2024-10-01")
|
||||
dt2 = pd.Timestamp("2024-10-31")
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "1mo"))
|
||||
|
||||
def test_different_months(self):
|
||||
dt1 = pd.Timestamp("2024-10-31")
|
||||
dt2 = pd.Timestamp("2024-11-01")
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt2, "1mo"))
|
||||
|
||||
def test_month_year_boundary(self):
|
||||
dt1 = pd.Timestamp("2024-12-15")
|
||||
dt2 = pd.Timestamp("2025-01-15")
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt2, "1mo"))
|
||||
|
||||
def test_standard_quarters(self):
|
||||
q1_start = datetime(2023, 1, 1)
|
||||
self.assertTrue(_dts_in_same_interval(q1_start, datetime(2023, 1, 15), '3mo'))
|
||||
self.assertTrue(_dts_in_same_interval(q1_start, datetime(2023, 3, 31), '3mo'))
|
||||
self.assertFalse(_dts_in_same_interval(q1_start, datetime(2023, 4, 1), '3mo'))
|
||||
self.assertFalse(_dts_in_same_interval(q1_start, datetime(2022, 1, 15), '3mo')) # Previous year
|
||||
self.assertFalse(_dts_in_same_interval(q1_start, datetime(2024, 1, 15), '3mo')) # Next year
|
||||
|
||||
q2_start = datetime(2023, 4, 1)
|
||||
self.assertTrue(_dts_in_same_interval(q2_start, datetime(2023, 5, 15), '3mo'))
|
||||
self.assertTrue(_dts_in_same_interval(q2_start, datetime(2023, 6, 30), '3mo'))
|
||||
self.assertFalse(_dts_in_same_interval(q2_start, datetime(2023, 7, 1), '3mo'))
|
||||
|
||||
def test_nonstandard_quarters(self):
|
||||
q1_start = datetime(2023, 2, 1)
|
||||
# Same quarter
|
||||
self.assertTrue(_dts_in_same_interval(q1_start, datetime(2023, 3, 1), '3mo'))
|
||||
self.assertTrue(_dts_in_same_interval(q1_start, datetime(2023, 4, 25), '3mo'))
|
||||
# Different quarters
|
||||
self.assertFalse(_dts_in_same_interval(q1_start, datetime(2023, 1, 25), '3mo')) # Before quarter start
|
||||
self.assertFalse(_dts_in_same_interval(q1_start, datetime(2023, 6, 1), '3mo')) # Start of next quarter
|
||||
self.assertFalse(_dts_in_same_interval(q1_start, datetime(2023, 9, 1), '3mo')) # Start of Q3
|
||||
|
||||
q2_start = datetime(2023, 5, 1)
|
||||
self.assertTrue(_dts_in_same_interval(q2_start, datetime(2023, 6, 1), '3mo'))
|
||||
self.assertTrue(_dts_in_same_interval(q2_start, datetime(2023, 7, 25), '3mo'))
|
||||
self.assertFalse(_dts_in_same_interval(q2_start, datetime(2023, 8, 1), '3mo'))
|
||||
|
||||
def test_cross_year_quarters(self):
|
||||
q4_start = datetime(2023, 11, 1)
|
||||
|
||||
# Same quarter, different year
|
||||
self.assertTrue(_dts_in_same_interval(q4_start, datetime(2023, 11, 15), '3mo'))
|
||||
self.assertTrue(_dts_in_same_interval(q4_start, datetime(2024, 1, 15), '3mo'))
|
||||
self.assertTrue(_dts_in_same_interval(q4_start, datetime(2024, 1, 25), '3mo'))
|
||||
|
||||
# Different quarters
|
||||
self.assertFalse(_dts_in_same_interval(q4_start, datetime(2024, 2, 1), '3mo')) # Start of next quarter
|
||||
self.assertFalse(_dts_in_same_interval(q4_start, datetime(2023, 10, 14), '3mo')) # Before quarter start
|
||||
|
||||
def test_hourly_interval(self):
|
||||
dt1 = pd.Timestamp("2024-10-15 14:00:00")
|
||||
dt2 = pd.Timestamp("2024-10-15 14:59:59")
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "1h"))
|
||||
|
||||
dt3 = pd.Timestamp("2024-10-15 15:00:00")
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt3, "1h"))
|
||||
|
||||
def test_custom_intervals(self):
|
||||
# Test 4 hour interval
|
||||
dt1 = pd.Timestamp("2024-10-15 10:00:00")
|
||||
dt2 = pd.Timestamp("2024-10-15 13:59:59")
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "4h"))
|
||||
|
||||
dt3 = pd.Timestamp("2024-10-15 14:00:00")
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt3, "4h"))
|
||||
|
||||
def test_minute_intervals(self):
|
||||
dt1 = pd.Timestamp("2024-10-15 10:30:00")
|
||||
dt2 = pd.Timestamp("2024-10-15 10:30:45")
|
||||
self.assertTrue(_dts_in_same_interval(dt1, dt2, "1min"))
|
||||
|
||||
dt3 = pd.Timestamp("2024-10-15 10:31:00")
|
||||
self.assertFalse(_dts_in_same_interval(dt1, dt3, "1min"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
|
||||
def suite():
|
||||
ts: TestSuite = unittest.TestSuite()
|
||||
ts.addTest(TestCache('Test cache'))
|
||||
ts.addTest(TestCacheNoPermission('Test cache no permission'))
|
||||
ts.addTest(TestPandas("Test pandas"))
|
||||
ts.addTest(TestUtils("Test utils"))
|
||||
return ts
|
||||
|
||||
@@ -21,14 +21,17 @@
|
||||
|
||||
from . import version
|
||||
from .search import Search
|
||||
from .lookup import Lookup
|
||||
from .ticker import Ticker
|
||||
from .tickers import Tickers
|
||||
from .multi import download
|
||||
from .live import WebSocket, AsyncWebSocket
|
||||
from .utils import enable_debug_mode
|
||||
from .cache import set_tz_cache_location
|
||||
from .domain.sector import Sector
|
||||
from .domain.industry import Industry
|
||||
from .domain.market import Market
|
||||
from .data import YfData
|
||||
|
||||
from .screener.query import EquityQuery, FundQuery
|
||||
from .screener.screener import screen, PREDEFINED_SCREENER_QUERIES
|
||||
@@ -39,6 +42,13 @@ __author__ = "Ran Aroussi"
|
||||
import warnings
|
||||
warnings.filterwarnings('default', category=DeprecationWarning, module='^yfinance')
|
||||
|
||||
__all__ = ['download', 'Market', 'Search', 'Ticker', 'Tickers', 'enable_debug_mode', 'set_tz_cache_location', 'Sector', 'Industry']
|
||||
__all__ = ['download', 'Market', 'Search', 'Lookup', 'Ticker', 'Tickers', 'enable_debug_mode', 'set_tz_cache_location', 'Sector', 'Industry', 'WebSocket', 'AsyncWebSocket']
|
||||
# screener stuff:
|
||||
__all__ += ['EquityQuery', 'FundQuery', 'screen', 'PREDEFINED_SCREENER_QUERIES']
|
||||
__all__ += ['EquityQuery', 'FundQuery', 'screen', 'PREDEFINED_SCREENER_QUERIES']
|
||||
|
||||
# Config stuff:
|
||||
_NOTSET=object()
|
||||
def set_config(proxy=_NOTSET):
|
||||
if proxy is not _NOTSET:
|
||||
YfData(proxy=proxy)
|
||||
__all__ += ["set_config"]
|
||||
|
||||
498
yfinance/base.py
@@ -21,19 +21,20 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from io import StringIO
|
||||
import json as _json
|
||||
import warnings
|
||||
from typing import Optional, Union
|
||||
from urllib.parse import quote as urlencode
|
||||
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import requests
|
||||
from datetime import date
|
||||
from curl_cffi import requests
|
||||
|
||||
|
||||
from . import utils, cache
|
||||
from .data import YfData
|
||||
from .exceptions import YFEarningsDateMissing, YFRateLimitError
|
||||
from .live import WebSocket
|
||||
from .scrapers.analysis import Analysis
|
||||
from .scrapers.fundamentals import Fundamentals
|
||||
from .scrapers.holders import Holders
|
||||
@@ -41,14 +42,15 @@ from .scrapers.quote import Quote, FastInfo
|
||||
from .scrapers.history import PriceHistory
|
||||
from .scrapers.funds import FundsData
|
||||
|
||||
from .const import _BASE_URL_, _ROOT_URL_
|
||||
from .const import _BASE_URL_, _ROOT_URL_, _QUERY1_URL_, _SENTINEL_
|
||||
|
||||
|
||||
_tz_info_fetch_ctr = 0
|
||||
|
||||
class TickerBase:
|
||||
def __init__(self, ticker, session=None, proxy=None):
|
||||
def __init__(self, ticker, session=None, proxy=_SENTINEL_):
|
||||
self.ticker = ticker.upper()
|
||||
self.proxy = proxy
|
||||
self.session = session
|
||||
self.session = session or requests.Session(impersonate="chrome")
|
||||
self._tz = None
|
||||
|
||||
self._isin = None
|
||||
@@ -60,11 +62,26 @@ class TickerBase:
|
||||
self._earnings = None
|
||||
self._financials = None
|
||||
|
||||
# accept isin as ticker
|
||||
if utils.is_isin(self.ticker):
|
||||
self.ticker = utils.get_ticker_by_isin(self.ticker, None, session)
|
||||
# raise an error if user tries to give empty ticker
|
||||
if self.ticker == "":
|
||||
raise ValueError("Empty ticker name")
|
||||
|
||||
self._data: YfData = YfData(session=session)
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
# accept isin as ticker
|
||||
if utils.is_isin(self.ticker):
|
||||
isin = self.ticker
|
||||
c = cache.get_isin_cache()
|
||||
self.ticker = c.lookup(isin)
|
||||
if not self.ticker:
|
||||
self.ticker = utils.get_ticker_by_isin(isin)
|
||||
if self.ticker == "":
|
||||
raise ValueError(f"Invalid ISIN number: {isin}")
|
||||
if self.ticker:
|
||||
c.store(isin, self.ticker)
|
||||
|
||||
# self._price_history = PriceHistory(self._data, self.ticker)
|
||||
self._price_history = None # lazy-load
|
||||
@@ -76,6 +93,9 @@ class TickerBase:
|
||||
|
||||
self._fast_info = None
|
||||
|
||||
self._message_handler = None
|
||||
self.ws = None
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def history(self, *args, **kwargs) -> pd.DataFrame:
|
||||
return self._lazy_load_price_history().history(*args, **kwargs)
|
||||
@@ -84,11 +104,10 @@ class TickerBase:
|
||||
|
||||
def _lazy_load_price_history(self):
|
||||
if self._price_history is None:
|
||||
self._price_history = PriceHistory(self._data, self.ticker, self._get_ticker_tz(self.proxy, timeout=10))
|
||||
self._price_history = PriceHistory(self._data, self.ticker, self._get_ticker_tz(timeout=10))
|
||||
return self._price_history
|
||||
|
||||
def _get_ticker_tz(self, proxy, timeout):
|
||||
proxy = proxy or self.proxy
|
||||
def _get_ticker_tz(self, timeout):
|
||||
if self._tz is not None:
|
||||
return self._tz
|
||||
c = cache.get_tz_cache()
|
||||
@@ -100,10 +119,20 @@ class TickerBase:
|
||||
tz = None
|
||||
|
||||
if tz is None:
|
||||
tz = self._fetch_ticker_tz(proxy, timeout)
|
||||
|
||||
tz = self._fetch_ticker_tz(timeout)
|
||||
if tz is None:
|
||||
# _fetch_ticker_tz works in 99.999% of cases.
|
||||
# For rare fail get from info.
|
||||
global _tz_info_fetch_ctr
|
||||
if _tz_info_fetch_ctr < 2:
|
||||
# ... but limit. If _fetch_ticker_tz() always
|
||||
# failing then bigger problem.
|
||||
_tz_info_fetch_ctr += 1
|
||||
for k in ['exchangeTimezoneName', 'timeZoneFullName']:
|
||||
if k in self.info:
|
||||
tz = self.info[k]
|
||||
break
|
||||
if utils.is_valid_timezone(tz):
|
||||
# info fetch is relatively slow so cache timezone
|
||||
c.store(self.ticker, tz)
|
||||
else:
|
||||
tz = None
|
||||
@@ -112,9 +141,8 @@ class TickerBase:
|
||||
return tz
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _fetch_ticker_tz(self, proxy, timeout):
|
||||
def _fetch_ticker_tz(self, timeout):
|
||||
# Query Yahoo for fast price data just to get returned timezone
|
||||
proxy = proxy or self.proxy
|
||||
logger = utils.get_yf_logger()
|
||||
|
||||
params = {"range": "1d", "interval": "1d"}
|
||||
@@ -123,7 +151,7 @@ class TickerBase:
|
||||
url = f"{_BASE_URL_}/v8/finance/chart/{self.ticker}"
|
||||
|
||||
try:
|
||||
data = self._data.cache_get(url=url, params=params, proxy=proxy, timeout=timeout)
|
||||
data = self._data.cache_get(url=url, params=params, timeout=timeout)
|
||||
data = data.json()
|
||||
except YFRateLimitError:
|
||||
# Must propagate this
|
||||
@@ -147,185 +175,245 @@ class TickerBase:
|
||||
logger.debug("-------------")
|
||||
return None
|
||||
|
||||
def get_recommendations(self, proxy=None, as_dict=False):
|
||||
def get_recommendations(self, proxy=_SENTINEL_, as_dict=False):
|
||||
"""
|
||||
Returns a DataFrame with the recommendations
|
||||
Columns: period strongBuy buy hold sell strongSell
|
||||
"""
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._quote.recommendations
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_recommendations_summary(self, proxy=None, as_dict=False):
|
||||
return self.get_recommendations(proxy=proxy, as_dict=as_dict)
|
||||
def get_recommendations_summary(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
def get_upgrades_downgrades(self, proxy=None, as_dict=False):
|
||||
return self.get_recommendations(as_dict=as_dict)
|
||||
|
||||
def get_upgrades_downgrades(self, proxy=_SENTINEL_, as_dict=False):
|
||||
"""
|
||||
Returns a DataFrame with the recommendations changes (upgrades/downgrades)
|
||||
Index: date of grade
|
||||
Columns: firm toGrade fromGrade action
|
||||
"""
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._quote.upgrades_downgrades
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_calendar(self, proxy=None) -> dict:
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
def get_calendar(self, proxy=_SENTINEL_) -> dict:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
return self._quote.calendar
|
||||
|
||||
def get_sec_filings(self, proxy=None) -> dict:
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
def get_sec_filings(self, proxy=_SENTINEL_) -> dict:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
return self._quote.sec_filings
|
||||
|
||||
def get_major_holders(self, proxy=None, as_dict=False):
|
||||
self._holders.proxy = proxy or self.proxy
|
||||
def get_major_holders(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._holders.major
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_institutional_holders(self, proxy=None, as_dict=False):
|
||||
self._holders.proxy = proxy or self.proxy
|
||||
def get_institutional_holders(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._holders.institutional
|
||||
if data is not None:
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_mutualfund_holders(self, proxy=None, as_dict=False):
|
||||
self._holders.proxy = proxy or self.proxy
|
||||
def get_mutualfund_holders(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._holders.mutualfund
|
||||
if data is not None:
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_insider_purchases(self, proxy=None, as_dict=False):
|
||||
self._holders.proxy = proxy or self.proxy
|
||||
def get_insider_purchases(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._holders.insider_purchases
|
||||
if data is not None:
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_insider_transactions(self, proxy=None, as_dict=False):
|
||||
self._holders.proxy = proxy or self.proxy
|
||||
def get_insider_transactions(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._holders.insider_transactions
|
||||
if data is not None:
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_insider_roster_holders(self, proxy=None, as_dict=False):
|
||||
self._holders.proxy = proxy or self.proxy
|
||||
def get_insider_roster_holders(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._holders.insider_roster
|
||||
if data is not None:
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_info(self, proxy=None) -> dict:
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
def get_info(self, proxy=_SENTINEL_) -> dict:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._quote.info
|
||||
return data
|
||||
|
||||
def get_fast_info(self, proxy=None):
|
||||
def get_fast_info(self, proxy=_SENTINEL_):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
if self._fast_info is None:
|
||||
self._fast_info = FastInfo(self, proxy=proxy)
|
||||
self._fast_info = FastInfo(self)
|
||||
return self._fast_info
|
||||
|
||||
@property
|
||||
def basic_info(self):
|
||||
warnings.warn("'Ticker.basic_info' is deprecated and will be removed in future, Switch to 'Ticker.fast_info'", DeprecationWarning)
|
||||
return self.fast_info
|
||||
def get_sustainability(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
def get_sustainability(self, proxy=None, as_dict=False):
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
data = self._quote.sustainability
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_analyst_price_targets(self, proxy=None) -> dict:
|
||||
def get_analyst_price_targets(self, proxy=_SENTINEL_) -> dict:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
"""
|
||||
Keys: current low high mean median
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
data = self._analysis.analyst_price_targets
|
||||
return data
|
||||
|
||||
def get_earnings_estimate(self, proxy=None, as_dict=False):
|
||||
def get_earnings_estimate(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
"""
|
||||
Index: 0q +1q 0y +1y
|
||||
Columns: numberOfAnalysts avg low high yearAgoEps growth
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
data = self._analysis.earnings_estimate
|
||||
return data.to_dict() if as_dict else data
|
||||
|
||||
def get_revenue_estimate(self, proxy=None, as_dict=False):
|
||||
def get_revenue_estimate(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
"""
|
||||
Index: 0q +1q 0y +1y
|
||||
Columns: numberOfAnalysts avg low high yearAgoRevenue growth
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
data = self._analysis.revenue_estimate
|
||||
return data.to_dict() if as_dict else data
|
||||
|
||||
def get_earnings_history(self, proxy=None, as_dict=False):
|
||||
def get_earnings_history(self, proxy=_SENTINEL_, as_dict=False):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
"""
|
||||
Index: pd.DatetimeIndex
|
||||
Columns: epsEstimate epsActual epsDifference surprisePercent
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
data = self._analysis.earnings_history
|
||||
return data.to_dict() if as_dict else data
|
||||
|
||||
def get_eps_trend(self, proxy=None, as_dict=False):
|
||||
def get_eps_trend(self, proxy=_SENTINEL_, as_dict=False):
|
||||
"""
|
||||
Index: 0q +1q 0y +1y
|
||||
Columns: current 7daysAgo 30daysAgo 60daysAgo 90daysAgo
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._analysis.eps_trend
|
||||
return data.to_dict() if as_dict else data
|
||||
|
||||
def get_eps_revisions(self, proxy=None, as_dict=False):
|
||||
def get_eps_revisions(self, proxy=_SENTINEL_, as_dict=False):
|
||||
"""
|
||||
Index: 0q +1q 0y +1y
|
||||
Columns: upLast7days upLast30days downLast7days downLast30days
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._analysis.eps_revisions
|
||||
return data.to_dict() if as_dict else data
|
||||
|
||||
def get_growth_estimates(self, proxy=None, as_dict=False):
|
||||
def get_growth_estimates(self, proxy=_SENTINEL_, as_dict=False):
|
||||
"""
|
||||
Index: 0q +1q 0y +1y +5y -5y
|
||||
Columns: stock industry sector index
|
||||
"""
|
||||
self._analysis.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._analysis.growth_estimates
|
||||
return data.to_dict() if as_dict else data
|
||||
|
||||
def get_earnings(self, proxy=None, as_dict=False, freq="yearly"):
|
||||
def get_earnings(self, proxy=_SENTINEL_, as_dict=False, freq="yearly"):
|
||||
"""
|
||||
:Parameters:
|
||||
as_dict: bool
|
||||
Return table as Python dict
|
||||
Default is False
|
||||
freq: str
|
||||
"yearly" or "quarterly"
|
||||
"yearly" or "quarterly" or "trailing"
|
||||
Default is "yearly"
|
||||
proxy: str
|
||||
Optional. Proxy server URL scheme
|
||||
Default is None
|
||||
"""
|
||||
self._fundamentals.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
if self._fundamentals.earnings is None:
|
||||
return None
|
||||
data = self._fundamentals.earnings[freq]
|
||||
@@ -336,7 +424,7 @@ class TickerBase:
|
||||
return dict_data
|
||||
return data
|
||||
|
||||
def get_income_stmt(self, proxy=None, as_dict=False, pretty=False, freq="yearly"):
|
||||
def get_income_stmt(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly"):
|
||||
"""
|
||||
:Parameters:
|
||||
as_dict: bool
|
||||
@@ -346,15 +434,14 @@ class TickerBase:
|
||||
Format row names nicely for readability
|
||||
Default is False
|
||||
freq: str
|
||||
"yearly" or "quarterly"
|
||||
"yearly" or "quarterly" or "trailing"
|
||||
Default is "yearly"
|
||||
proxy: str
|
||||
Optional. Proxy server URL scheme
|
||||
Default is None
|
||||
"""
|
||||
self._fundamentals.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._fundamentals.financials.get_income_time_series(freq=freq, proxy=proxy)
|
||||
data = self._fundamentals.financials.get_income_time_series(freq=freq)
|
||||
|
||||
if pretty:
|
||||
data = data.copy()
|
||||
@@ -363,13 +450,21 @@ class TickerBase:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_incomestmt(self, proxy=None, as_dict=False, pretty=False, freq="yearly"):
|
||||
def get_incomestmt(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly"):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
return self.get_income_stmt(proxy, as_dict, pretty, freq)
|
||||
|
||||
def get_financials(self, proxy=None, as_dict=False, pretty=False, freq="yearly"):
|
||||
def get_financials(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly"):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
return self.get_income_stmt(proxy, as_dict, pretty, freq)
|
||||
|
||||
def get_balance_sheet(self, proxy=None, as_dict=False, pretty=False, freq="yearly"):
|
||||
def get_balance_sheet(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly"):
|
||||
"""
|
||||
:Parameters:
|
||||
as_dict: bool
|
||||
@@ -381,13 +476,13 @@ class TickerBase:
|
||||
freq: str
|
||||
"yearly" or "quarterly"
|
||||
Default is "yearly"
|
||||
proxy: str
|
||||
Optional. Proxy server URL scheme
|
||||
Default is None
|
||||
"""
|
||||
self._fundamentals.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._fundamentals.financials.get_balance_sheet_time_series(freq=freq, proxy=proxy)
|
||||
|
||||
data = self._fundamentals.financials.get_balance_sheet_time_series(freq=freq)
|
||||
|
||||
if pretty:
|
||||
data = data.copy()
|
||||
@@ -396,10 +491,14 @@ class TickerBase:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_balancesheet(self, proxy=None, as_dict=False, pretty=False, freq="yearly"):
|
||||
def get_balancesheet(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly"):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
return self.get_balance_sheet(proxy, as_dict, pretty, freq)
|
||||
|
||||
def get_cash_flow(self, proxy=None, as_dict=False, pretty=False, freq="yearly") -> Union[pd.DataFrame, dict]:
|
||||
def get_cash_flow(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly") -> Union[pd.DataFrame, dict]:
|
||||
"""
|
||||
:Parameters:
|
||||
as_dict: bool
|
||||
@@ -411,13 +510,13 @@ class TickerBase:
|
||||
freq: str
|
||||
"yearly" or "quarterly"
|
||||
Default is "yearly"
|
||||
proxy: str
|
||||
Optional. Proxy server URL scheme
|
||||
Default is None
|
||||
"""
|
||||
self._fundamentals.proxy = proxy or self.proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
data = self._fundamentals.financials.get_cash_flow_time_series(freq=freq, proxy=proxy)
|
||||
|
||||
data = self._fundamentals.financials.get_cash_flow_time_series(freq=freq)
|
||||
|
||||
if pretty:
|
||||
data = data.copy()
|
||||
@@ -426,41 +525,61 @@ class TickerBase:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
def get_cashflow(self, proxy=None, as_dict=False, pretty=False, freq="yearly"):
|
||||
def get_cashflow(self, proxy=_SENTINEL_, as_dict=False, pretty=False, freq="yearly"):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
return self.get_cash_flow(proxy, as_dict, pretty, freq)
|
||||
|
||||
def get_dividends(self, proxy=None) -> pd.Series:
|
||||
return self._lazy_load_price_history().get_dividends(proxy)
|
||||
def get_dividends(self, proxy=_SENTINEL_, period="max") -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
return self._lazy_load_price_history().get_dividends(period=period)
|
||||
|
||||
def get_capital_gains(self, proxy=None) -> pd.Series:
|
||||
return self._lazy_load_price_history().get_capital_gains(proxy)
|
||||
def get_capital_gains(self, proxy=_SENTINEL_, period="max") -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
return self._lazy_load_price_history().get_capital_gains(period=period)
|
||||
|
||||
def get_splits(self, proxy=None) -> pd.Series:
|
||||
return self._lazy_load_price_history().get_splits(proxy)
|
||||
def get_splits(self, proxy=_SENTINEL_, period="max") -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
return self._lazy_load_price_history().get_splits(period=period)
|
||||
|
||||
def get_actions(self, proxy=None) -> pd.Series:
|
||||
return self._lazy_load_price_history().get_actions(proxy)
|
||||
def get_actions(self, proxy=_SENTINEL_, period="max") -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
return self._lazy_load_price_history().get_actions(period=period)
|
||||
|
||||
def get_shares(self, proxy=_SENTINEL_, as_dict=False) -> Union[pd.DataFrame, dict]:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
def get_shares(self, proxy=None, as_dict=False) -> Union[pd.DataFrame, dict]:
|
||||
self._fundamentals.proxy = proxy or self.proxy
|
||||
data = self._fundamentals.shares
|
||||
if as_dict:
|
||||
return data.to_dict()
|
||||
return data
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def get_shares_full(self, start=None, end=None, proxy=None):
|
||||
def get_shares_full(self, start=None, end=None, proxy=_SENTINEL_):
|
||||
logger = utils.get_yf_logger()
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
# Process dates
|
||||
tz = self._get_ticker_tz(proxy=proxy, timeout=10)
|
||||
tz = self._get_ticker_tz(timeout=10)
|
||||
dt_now = pd.Timestamp.utcnow().tz_convert(tz)
|
||||
if start is not None:
|
||||
start_ts = utils._parse_user_dt(start, tz)
|
||||
start = pd.Timestamp.fromtimestamp(start_ts).tz_localize("UTC").tz_convert(tz)
|
||||
start = utils._parse_user_dt(start, tz)
|
||||
if end is not None:
|
||||
end_ts = utils._parse_user_dt(end, tz)
|
||||
end = pd.Timestamp.fromtimestamp(end_ts).tz_localize("UTC").tz_convert(tz)
|
||||
end = utils._parse_user_dt(end, tz)
|
||||
if end is None:
|
||||
end = dt_now
|
||||
if start is None:
|
||||
@@ -475,7 +594,7 @@ class TickerBase:
|
||||
ts_url_base = f"https://query2.finance.yahoo.com/ws/fundamentals-timeseries/v1/finance/timeseries/{self.ticker}?symbol={self.ticker}"
|
||||
shares_url = f"{ts_url_base}&period1={int(start.timestamp())}&period2={int(end.timestamp())}"
|
||||
try:
|
||||
json_data = self._data.cache_get(url=shares_url, proxy=proxy)
|
||||
json_data = self._data.cache_get(url=shares_url)
|
||||
json_data = json_data.json()
|
||||
except (_json.JSONDecodeError, requests.exceptions.RequestException):
|
||||
logger.error(f"{self.ticker}: Yahoo web request for share count failed")
|
||||
@@ -501,7 +620,11 @@ class TickerBase:
|
||||
df = df.sort_index()
|
||||
return df
|
||||
|
||||
def get_isin(self, proxy=None) -> Optional[str]:
|
||||
def get_isin(self, proxy=_SENTINEL_) -> Optional[str]:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
# *** experimental ***
|
||||
if self._isin is not None:
|
||||
return self._isin
|
||||
@@ -514,7 +637,6 @@ class TickerBase:
|
||||
|
||||
q = ticker
|
||||
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
if self._quote.info is None:
|
||||
# Don't print error message cause self._quote.info will print one
|
||||
return None
|
||||
@@ -522,7 +644,7 @@ class TickerBase:
|
||||
q = self._quote.info['shortName']
|
||||
|
||||
url = f'https://markets.businessinsider.com/ajax/SearchController_Suggest?max_results=25&query={urlencode(q)}'
|
||||
data = self._data.cache_get(url=url, proxy=proxy).text
|
||||
data = self._data.cache_get(url=url).text
|
||||
|
||||
search_str = f'"{ticker}|'
|
||||
if search_str not in data:
|
||||
@@ -538,13 +660,17 @@ class TickerBase:
|
||||
self._isin = data.split(search_str)[1].split('"')[0].split('|')[0]
|
||||
return self._isin
|
||||
|
||||
def get_news(self, count=10, tab="news", proxy=None) -> list:
|
||||
def get_news(self, count=10, tab="news", proxy=_SENTINEL_) -> list:
|
||||
"""Allowed options for tab: "news", "all", "press releases"""
|
||||
if self._news:
|
||||
return self._news
|
||||
|
||||
logger = utils.get_yf_logger()
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
tab_queryrefs = {
|
||||
"all": "newsAll",
|
||||
"news": "latestNews",
|
||||
@@ -563,7 +689,7 @@ class TickerBase:
|
||||
}
|
||||
}
|
||||
|
||||
data = self._data.post(url, body=payload, proxy=proxy)
|
||||
data = self._data.post(url, body=payload)
|
||||
if data is None or "Will be right back" in data.text:
|
||||
raise RuntimeError("*** YAHOO! FINANCE IS CURRENTLY DOWN! ***\n"
|
||||
"Our engineers are working quickly to resolve "
|
||||
@@ -580,7 +706,7 @@ class TickerBase:
|
||||
return self._news
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def get_earnings_dates(self, limit=12, proxy=None) -> Optional[pd.DataFrame]:
|
||||
def get_earnings_dates(self, limit=12, proxy=_SENTINEL_) -> Optional[pd.DataFrame]:
|
||||
"""
|
||||
Get earning dates (future and historic)
|
||||
|
||||
@@ -588,105 +714,93 @@ class TickerBase:
|
||||
limit (int): max amount of upcoming and recent earnings dates to return.
|
||||
Default value 12 should return next 4 quarters and last 8 quarters.
|
||||
Increase if more history is needed.
|
||||
proxy: requests proxy to use.
|
||||
|
||||
Returns:
|
||||
pd.DataFrame
|
||||
"""
|
||||
if self._earnings_dates and limit in self._earnings_dates:
|
||||
return self._earnings_dates[limit]
|
||||
|
||||
logger = utils.get_yf_logger()
|
||||
|
||||
page_size = min(limit, 100) # YF caps at 100, don't go higher
|
||||
page_offset = 0
|
||||
dates = None
|
||||
while True:
|
||||
url = f"{_ROOT_URL_}/calendar/earnings?day={date.today()}&symbol={self.ticker}&offset={page_offset}&size={page_size}"
|
||||
data = self._data.cache_get(url=url, proxy=proxy).text
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
if "Will be right back" in data:
|
||||
raise RuntimeError("*** YAHOO! FINANCE IS CURRENTLY DOWN! ***\n"
|
||||
"Our engineers are working quickly to resolve "
|
||||
"the issue. Thank you for your patience.")
|
||||
clamped_limit = min(limit, 100) # YF caps at 100, don't go higher
|
||||
|
||||
try:
|
||||
data = pd.read_html(StringIO(data))[0]
|
||||
except ValueError:
|
||||
if page_offset == 0:
|
||||
# Should not fail on first page
|
||||
if "Showing Earnings for:" in data:
|
||||
# Actually YF was successful, problem is company doesn't have earnings history
|
||||
dates = utils.empty_earnings_dates_df()
|
||||
break
|
||||
if dates is None:
|
||||
dates = data
|
||||
else:
|
||||
dates = pd.concat([dates, data], axis=0)
|
||||
if self._earnings_dates and clamped_limit in self._earnings_dates:
|
||||
return self._earnings_dates[clamped_limit]
|
||||
|
||||
page_offset += page_size
|
||||
# got less data then we asked for or already fetched all we requested, no need to fetch more pages
|
||||
if len(data) < page_size or len(dates) >= limit:
|
||||
dates = dates.iloc[:limit]
|
||||
break
|
||||
else:
|
||||
# do not fetch more than needed next time
|
||||
page_size = min(limit - len(dates), page_size)
|
||||
# Fetch data
|
||||
url = f"{_QUERY1_URL_}/v1/finance/visualization"
|
||||
params = {"lang": "en-US", "region": "US"}
|
||||
body = {
|
||||
"size": clamped_limit,
|
||||
"query": { "operator": "eq", "operands": ["ticker", self.ticker] },
|
||||
"sortField": "startdatetime",
|
||||
"sortType": "DESC",
|
||||
"entityIdType": "earnings",
|
||||
"includeFields": ["startdatetime", "timeZoneShortName", "epsestimate", "epsactual", "epssurprisepct", "eventtype"]
|
||||
}
|
||||
response = self._data.post(url, params=params, body=body)
|
||||
json_data = response.json()
|
||||
|
||||
if dates is None or dates.shape[0] == 0:
|
||||
# Extract data
|
||||
columns = [row['label'] for row in json_data['finance']['result'][0]['documents'][0]['columns']]
|
||||
rows = json_data['finance']['result'][0]['documents'][0]['rows']
|
||||
df = pd.DataFrame(rows, columns=columns)
|
||||
|
||||
if df.empty:
|
||||
_exception = YFEarningsDateMissing(self.ticker)
|
||||
err_msg = str(_exception)
|
||||
logger.error(f'{self.ticker}: {err_msg}')
|
||||
return None
|
||||
dates = dates.reset_index(drop=True)
|
||||
|
||||
# Drop redundant columns
|
||||
dates = dates.drop(["Symbol", "Company"], axis=1)
|
||||
# Convert eventtype
|
||||
# - 1 = earnings call (manually confirmed)
|
||||
# - 2 = earnings report
|
||||
# - 11 = stockholders meeting (manually confirmed)
|
||||
df['Event Type'] = df['Event Type'].replace('^1$', 'Call', regex=True)
|
||||
df['Event Type'] = df['Event Type'].replace('^2$', 'Earnings', regex=True)
|
||||
df['Event Type'] = df['Event Type'].replace('^11$', 'Meeting', regex=True)
|
||||
|
||||
# Compatibility
|
||||
dates = dates.rename(columns={'Surprise (%)': 'Surprise(%)'})
|
||||
|
||||
# Drop empty rows
|
||||
for i in range(len(dates)-1, -1, -1):
|
||||
if dates.iloc[i].isna().all():
|
||||
dates = dates.drop(i)
|
||||
# Calculate earnings date
|
||||
df['Earnings Date'] = pd.to_datetime(df['Event Start Date'])
|
||||
tz = self._get_ticker_tz(timeout=30)
|
||||
if df['Earnings Date'].dt.tz is None:
|
||||
df['Earnings Date'] = df['Earnings Date'].dt.tz_localize(tz)
|
||||
else:
|
||||
df['Earnings Date'] = df['Earnings Date'].dt.tz_convert(tz)
|
||||
|
||||
# Convert types
|
||||
for cn in ["EPS Estimate", "Reported EPS", "Surprise(%)"]:
|
||||
dates.loc[dates[cn] == '-', cn] = float("nan")
|
||||
dates[cn] = dates[cn].astype(float)
|
||||
columns_to_update = ['Surprise (%)', 'EPS Estimate', 'Reported EPS']
|
||||
df[columns_to_update] = df[columns_to_update].astype('float64').replace(0.0, np.nan)
|
||||
|
||||
# Parse earnings date string
|
||||
cn = "Earnings Date"
|
||||
try:
|
||||
dates_backup = dates.copy()
|
||||
# - extract timezone because Yahoo stopped returning in UTC
|
||||
tzy = dates[cn].str.split(' ').str.get(-1)
|
||||
tzy[tzy.isin(['EDT', 'EST'])] = 'US/Eastern'
|
||||
# - tidy date string
|
||||
dates[cn] = dates[cn].str.split(' ').str[:-1].str.join(' ')
|
||||
dates[cn] = dates[cn].replace(' at', ',', regex=True)
|
||||
# - parse
|
||||
dates[cn] = pd.to_datetime(dates[cn], format="%B %d, %Y, %I %p")
|
||||
# - convert to exchange timezone
|
||||
self._quote.proxy = proxy or self.proxy
|
||||
tz = self._get_ticker_tz(proxy=proxy, timeout=30)
|
||||
dates[cn] = [dates[cn].iloc[i].tz_localize(tzy.iloc[i], ambiguous=True).tz_convert(tz) for i in range(len(dates))]
|
||||
# Format the dataframe
|
||||
df.drop(['Event Start Date', 'Timezone short name'], axis=1, inplace=True)
|
||||
df.set_index('Earnings Date', inplace=True)
|
||||
df.rename(columns={'Surprise (%)': 'Surprise(%)'}, inplace=True) # Compatibility
|
||||
|
||||
dates = dates.set_index("Earnings Date")
|
||||
except Exception as e:
|
||||
utils.get_yf_logger().info(f"{self.ticker}: Problem parsing earnings_dates: {str(e)}")
|
||||
dates = dates_backup
|
||||
self._earnings_dates[clamped_limit] = df
|
||||
return df
|
||||
|
||||
self._earnings_dates[limit] = dates
|
||||
def get_history_metadata(self, proxy=_SENTINEL_) -> dict:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
return dates
|
||||
|
||||
def get_history_metadata(self, proxy=None) -> dict:
|
||||
return self._lazy_load_price_history().get_history_metadata(proxy)
|
||||
|
||||
def get_funds_data(self, proxy=None) -> Optional[FundsData]:
|
||||
def get_funds_data(self, proxy=_SENTINEL_) -> Optional[FundsData]:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
if not self._funds_data:
|
||||
self._funds_data = FundsData(self._data, self.ticker)
|
||||
|
||||
return self._funds_data
|
||||
|
||||
def live(self, message_handler=None, verbose=True):
|
||||
self._message_handler = message_handler
|
||||
|
||||
self.ws = WebSocket(verbose=verbose)
|
||||
self.ws.subscribe(self.ticker)
|
||||
self.ws.listen(self._message_handler)
|
||||
|
||||
@@ -3,13 +3,15 @@ from threading import Lock
|
||||
import os as _os
|
||||
import platformdirs as _ad
|
||||
import atexit as _atexit
|
||||
import datetime as _datetime
|
||||
import datetime as _dt
|
||||
import pickle as _pkl
|
||||
|
||||
from .utils import get_yf_logger
|
||||
|
||||
_cache_init_lock = Lock()
|
||||
|
||||
|
||||
|
||||
# --------------
|
||||
# TimeZone cache
|
||||
# --------------
|
||||
@@ -105,7 +107,7 @@ _atexit.register(_TzDBManager.close_db)
|
||||
|
||||
|
||||
tz_db_proxy = _peewee.Proxy()
|
||||
class _KV(_peewee.Model):
|
||||
class _TZ_KV(_peewee.Model):
|
||||
key = _peewee.CharField(primary_key=True)
|
||||
value = _peewee.CharField(null=True)
|
||||
|
||||
@@ -146,11 +148,11 @@ class _TzCache:
|
||||
db.connect()
|
||||
tz_db_proxy.initialize(db)
|
||||
try:
|
||||
db.create_tables([_KV])
|
||||
db.create_tables([_TZ_KV])
|
||||
except _peewee.OperationalError as e:
|
||||
if 'WITHOUT' in str(e):
|
||||
_KV._meta.without_rowid = False
|
||||
db.create_tables([_KV])
|
||||
_TZ_KV._meta.without_rowid = False
|
||||
db.create_tables([_TZ_KV])
|
||||
else:
|
||||
raise
|
||||
self.initialised = 1 # success
|
||||
@@ -166,8 +168,8 @@ class _TzCache:
|
||||
return None
|
||||
|
||||
try:
|
||||
return _KV.get(_KV.key == key).value
|
||||
except _KV.DoesNotExist:
|
||||
return _TZ_KV.get(_TZ_KV.key == key).value
|
||||
except _TZ_KV.DoesNotExist:
|
||||
return None
|
||||
|
||||
def store(self, key, value):
|
||||
@@ -185,18 +187,18 @@ class _TzCache:
|
||||
return
|
||||
try:
|
||||
if value is None:
|
||||
q = _KV.delete().where(_KV.key == key)
|
||||
q = _TZ_KV.delete().where(_TZ_KV.key == key)
|
||||
q.execute()
|
||||
return
|
||||
with db.atomic():
|
||||
_KV.insert(key=key, value=value).execute()
|
||||
_TZ_KV.insert(key=key, value=value).execute()
|
||||
except _peewee.IntegrityError:
|
||||
# Integrity error means the key already exists. Try updating the key.
|
||||
old_value = self.lookup(key)
|
||||
if old_value != value:
|
||||
get_yf_logger().debug(f"Value for key {key} changed from {old_value} to {value}.")
|
||||
with db.atomic():
|
||||
q = _KV.update(value=value).where(_KV.key == key)
|
||||
q = _TZ_KV.update(value=value).where(_TZ_KV.key == key)
|
||||
q.execute()
|
||||
|
||||
|
||||
@@ -301,16 +303,16 @@ class ISODateTimeField(_peewee.DateTimeField):
|
||||
# because user discovered peewee allowed an invalid datetime
|
||||
# to get written.
|
||||
def db_value(self, value):
|
||||
if value and isinstance(value, _datetime.datetime):
|
||||
if value and isinstance(value, _dt.datetime):
|
||||
return value.isoformat()
|
||||
return super().db_value(value)
|
||||
def python_value(self, value):
|
||||
if value and isinstance(value, str) and 'T' in value:
|
||||
return _datetime.datetime.fromisoformat(value)
|
||||
return _dt.datetime.fromisoformat(value)
|
||||
return super().python_value(value)
|
||||
class _CookieSchema(_peewee.Model):
|
||||
strategy = _peewee.CharField(primary_key=True)
|
||||
fetch_date = ISODateTimeField(default=_datetime.datetime.now)
|
||||
fetch_date = ISODateTimeField(default=_dt.datetime.now)
|
||||
|
||||
# Which cookie type depends on strategy
|
||||
cookie_bytes = _peewee.BlobField()
|
||||
@@ -374,7 +376,7 @@ class _CookieCache:
|
||||
try:
|
||||
data = _CookieSchema.get(_CookieSchema.strategy == strategy)
|
||||
cookie = _pkl.loads(data.cookie_bytes)
|
||||
return {'cookie':cookie, 'age':_datetime.datetime.now()-data.fetch_date}
|
||||
return {'cookie':cookie, 'age':_dt.datetime.now()-data.fetch_date}
|
||||
except _CookieSchema.DoesNotExist:
|
||||
return None
|
||||
|
||||
@@ -415,6 +417,211 @@ def get_cookie_cache():
|
||||
|
||||
|
||||
|
||||
# --------------
|
||||
# ISIN cache
|
||||
# --------------
|
||||
|
||||
class _ISINCacheException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class _ISINCacheDummy:
|
||||
"""Dummy cache to use if isin cache is disabled"""
|
||||
|
||||
def lookup(self, isin):
|
||||
return None
|
||||
|
||||
def store(self, isin, tkr):
|
||||
pass
|
||||
|
||||
@property
|
||||
def tz_db(self):
|
||||
return None
|
||||
|
||||
|
||||
class _ISINCacheManager:
|
||||
_isin_cache = None
|
||||
|
||||
@classmethod
|
||||
def get_isin_cache(cls):
|
||||
if cls._isin_cache is None:
|
||||
with _cache_init_lock:
|
||||
cls._initialise()
|
||||
return cls._isin_cache
|
||||
|
||||
@classmethod
|
||||
def _initialise(cls, cache_dir=None):
|
||||
cls._isin_cache = _ISINCache()
|
||||
|
||||
|
||||
class _ISINDBManager:
|
||||
_db = None
|
||||
_cache_dir = _os.path.join(_ad.user_cache_dir(), "py-yfinance")
|
||||
|
||||
@classmethod
|
||||
def get_database(cls):
|
||||
if cls._db is None:
|
||||
cls._initialise()
|
||||
return cls._db
|
||||
|
||||
@classmethod
|
||||
def close_db(cls):
|
||||
if cls._db is not None:
|
||||
try:
|
||||
cls._db.close()
|
||||
except Exception:
|
||||
# Must discard exceptions because Python trying to quit.
|
||||
pass
|
||||
|
||||
|
||||
@classmethod
|
||||
def _initialise(cls, cache_dir=None):
|
||||
if cache_dir is not None:
|
||||
cls._cache_dir = cache_dir
|
||||
|
||||
if not _os.path.isdir(cls._cache_dir):
|
||||
try:
|
||||
_os.makedirs(cls._cache_dir)
|
||||
except OSError as err:
|
||||
raise _ISINCacheException(f"Error creating ISINCache folder: '{cls._cache_dir}' reason: {err}")
|
||||
elif not (_os.access(cls._cache_dir, _os.R_OK) and _os.access(cls._cache_dir, _os.W_OK)):
|
||||
raise _ISINCacheException(f"Cannot read and write in ISINCache folder: '{cls._cache_dir}'")
|
||||
|
||||
cls._db = _peewee.SqliteDatabase(
|
||||
_os.path.join(cls._cache_dir, 'isin-tkr.db'),
|
||||
pragmas={'journal_mode': 'wal', 'cache_size': -64}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def set_location(cls, new_cache_dir):
|
||||
if cls._db is not None:
|
||||
cls._db.close()
|
||||
cls._db = None
|
||||
cls._cache_dir = new_cache_dir
|
||||
|
||||
@classmethod
|
||||
def get_location(cls):
|
||||
return cls._cache_dir
|
||||
|
||||
# close DB when Python exists
|
||||
_atexit.register(_ISINDBManager.close_db)
|
||||
|
||||
|
||||
isin_db_proxy = _peewee.Proxy()
|
||||
class _ISIN_KV(_peewee.Model):
|
||||
key = _peewee.CharField(primary_key=True)
|
||||
value = _peewee.CharField(null=True)
|
||||
created_at = _peewee.DateTimeField(default=_dt.datetime.now)
|
||||
|
||||
class Meta:
|
||||
database = isin_db_proxy
|
||||
without_rowid = True
|
||||
|
||||
|
||||
class _ISINCache:
|
||||
def __init__(self):
|
||||
self.initialised = -1
|
||||
self.db = None
|
||||
self.dummy = False
|
||||
|
||||
def get_db(self):
|
||||
if self.db is not None:
|
||||
return self.db
|
||||
|
||||
try:
|
||||
self.db = _ISINDBManager.get_database()
|
||||
except _ISINCacheException as err:
|
||||
get_yf_logger().info(f"Failed to create ISINCache, reason: {err}. "
|
||||
"ISINCache will not be used. "
|
||||
"Tip: You can direct cache to use a different location with 'set_isin_cache_location(mylocation)'")
|
||||
self.dummy = True
|
||||
return None
|
||||
return self.db
|
||||
|
||||
def initialise(self):
|
||||
if self.initialised != -1:
|
||||
return
|
||||
|
||||
db = self.get_db()
|
||||
if db is None:
|
||||
self.initialised = 0 # failure
|
||||
return
|
||||
|
||||
db.connect()
|
||||
isin_db_proxy.initialize(db)
|
||||
try:
|
||||
db.create_tables([_ISIN_KV])
|
||||
except _peewee.OperationalError as e:
|
||||
if 'WITHOUT' in str(e):
|
||||
_ISIN_KV._meta.without_rowid = False
|
||||
db.create_tables([_ISIN_KV])
|
||||
else:
|
||||
raise
|
||||
self.initialised = 1 # success
|
||||
|
||||
def lookup(self, key):
|
||||
if self.dummy:
|
||||
return None
|
||||
|
||||
if self.initialised == -1:
|
||||
self.initialise()
|
||||
|
||||
if self.initialised == 0: # failure
|
||||
return None
|
||||
|
||||
try:
|
||||
return _ISIN_KV.get(_ISIN_KV.key == key).value
|
||||
except _ISIN_KV.DoesNotExist:
|
||||
return None
|
||||
|
||||
def store(self, key, value):
|
||||
if self.dummy:
|
||||
return
|
||||
|
||||
if self.initialised == -1:
|
||||
self.initialise()
|
||||
|
||||
if self.initialised == 0: # failure
|
||||
return
|
||||
|
||||
db = self.get_db()
|
||||
if db is None:
|
||||
return
|
||||
try:
|
||||
if value is None:
|
||||
q = _ISIN_KV.delete().where(_ISIN_KV.key == key)
|
||||
q.execute()
|
||||
return
|
||||
|
||||
# Remove existing rows with same value that are older than 1 week
|
||||
one_week_ago = _dt.datetime.now() - _dt.timedelta(weeks=1)
|
||||
old_rows_query = _ISIN_KV.delete().where(
|
||||
(_ISIN_KV.value == value) &
|
||||
(_ISIN_KV.created_at < one_week_ago)
|
||||
)
|
||||
old_rows_query.execute()
|
||||
|
||||
with db.atomic():
|
||||
_ISIN_KV.insert(key=key, value=value).execute()
|
||||
|
||||
except _peewee.IntegrityError:
|
||||
# Integrity error means the key already exists. Try updating the key.
|
||||
old_value = self.lookup(key)
|
||||
if old_value != value:
|
||||
get_yf_logger().debug(f"Value for key {key} changed from {old_value} to {value}.")
|
||||
with db.atomic():
|
||||
q = _ISIN_KV.update(value=value, created_at=_dt.datetime.now()).where(_ISIN_KV.key == key)
|
||||
q.execute()
|
||||
|
||||
|
||||
def get_isin_cache():
|
||||
return _ISINCacheManager.get_isin_cache()
|
||||
|
||||
|
||||
# --------------
|
||||
# Utils
|
||||
# --------------
|
||||
|
||||
def set_cache_location(cache_dir: str):
|
||||
"""
|
||||
Sets the path to create the "py-yfinance" cache folder in.
|
||||
@@ -425,6 +632,7 @@ def set_cache_location(cache_dir: str):
|
||||
"""
|
||||
_TzDBManager.set_location(cache_dir)
|
||||
_CookieDBManager.set_location(cache_dir)
|
||||
_ISINDBManager.set_location(cache_dir)
|
||||
|
||||
def set_tz_cache_location(cache_dir: str):
|
||||
set_cache_location(cache_dir)
|
||||
|
||||
@@ -2,6 +2,8 @@ _QUERY1_URL_ = 'https://query1.finance.yahoo.com'
|
||||
_BASE_URL_ = 'https://query2.finance.yahoo.com'
|
||||
_ROOT_URL_ = 'https://finance.yahoo.com'
|
||||
|
||||
_SENTINEL_ = object()
|
||||
|
||||
fundamentals_keys = {
|
||||
'financials': ["TaxEffectOfUnusualItems", "TaxRateForCalcs", "NormalizedEBITDA", "NormalizedDilutedEPS",
|
||||
"NormalizedBasicEPS", "TotalUnusualItems", "TotalUnusualItemsExcludingGoodwill",
|
||||
@@ -624,3 +626,21 @@ EQUITY_SCREENER_FIELDS = {
|
||||
"highest_controversy"}
|
||||
}
|
||||
EQUITY_SCREENER_FIELDS = merge_two_level_dicts(EQUITY_SCREENER_FIELDS, COMMON_SCREENER_FIELDS)
|
||||
|
||||
USER_AGENTS = [
|
||||
# Chrome
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
|
||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
|
||||
|
||||
# Firefox
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0",
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14.7; rv:135.0) Gecko/20100101 Firefox/135.0",
|
||||
"Mozilla/5.0 (X11; Linux i686; rv:135.0) Gecko/20100101 Firefox/135.0",
|
||||
|
||||
# Safari
|
||||
"Mozilla/5.0 (Macintosh; Intel Mac OS X 14_7_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15",
|
||||
|
||||
# Edge
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/131.0.2903.86"
|
||||
]
|
||||
|
||||
284
yfinance/data.py
@@ -1,7 +1,7 @@
|
||||
import functools
|
||||
from functools import lru_cache
|
||||
|
||||
import requests as requests
|
||||
from curl_cffi import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import datetime
|
||||
|
||||
@@ -10,7 +10,7 @@ from frozendict import frozendict
|
||||
from . import utils, cache
|
||||
import threading
|
||||
|
||||
from .exceptions import YFRateLimitError
|
||||
from .exceptions import YFRateLimitError, YFDataException
|
||||
|
||||
cache_maxsize = 64
|
||||
|
||||
@@ -49,7 +49,13 @@ class SingletonMeta(type):
|
||||
instance = super().__call__(*args, **kwargs)
|
||||
cls._instances[cls] = instance
|
||||
else:
|
||||
cls._instances[cls]._set_session(*args, **kwargs)
|
||||
# Update the existing instance
|
||||
if 'session' in kwargs or (args and len(args) > 0):
|
||||
session = kwargs.get('session') if 'session' in kwargs else args[0]
|
||||
cls._instances[cls]._set_session(session)
|
||||
if 'proxy' in kwargs or (args and len(args) > 1):
|
||||
proxy = kwargs.get('proxy') if 'proxy' in kwargs else args[1]
|
||||
cls._instances[cls]._set_proxy(proxy)
|
||||
return cls._instances[cls]
|
||||
|
||||
|
||||
@@ -58,10 +64,8 @@ class YfData(metaclass=SingletonMeta):
|
||||
Have one place to retrieve data from Yahoo API in order to ease caching and speed up operations.
|
||||
Singleton means one session one cookie shared by all threads.
|
||||
"""
|
||||
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 __init__(self, session=None):
|
||||
def __init__(self, session=None, proxy=None):
|
||||
self._crumb = None
|
||||
self._cookie = None
|
||||
|
||||
@@ -72,16 +76,16 @@ class YfData(metaclass=SingletonMeta):
|
||||
|
||||
self._cookie_lock = threading.Lock()
|
||||
|
||||
self._set_session(session or requests.Session())
|
||||
self._session, self._proxy = None, None
|
||||
self._set_session(session or requests.Session(impersonate="chrome"))
|
||||
self._set_proxy(proxy)
|
||||
|
||||
def _set_session(self, session):
|
||||
if session is None:
|
||||
return
|
||||
with self._cookie_lock:
|
||||
self._session = session
|
||||
|
||||
try:
|
||||
self._session.cache
|
||||
session.cache
|
||||
except AttributeError:
|
||||
# Not caching
|
||||
self._session_is_caching = False
|
||||
@@ -90,8 +94,25 @@ class YfData(metaclass=SingletonMeta):
|
||||
# Can't simply use a non-caching session to fetch cookie & crumb,
|
||||
# because then the caching-session won't have cookie.
|
||||
self._session_is_caching = True
|
||||
from requests_cache import DO_NOT_CACHE
|
||||
self._expire_after = DO_NOT_CACHE
|
||||
# But since switch to curl_cffi, can't use requests_cache with it.
|
||||
raise YFDataException("request_cache sessions don't work with curl_cffi, which is necessary now for Yahoo API. Solution: stop setting session, let YF handle.")
|
||||
|
||||
if not isinstance(session, requests.session.Session):
|
||||
raise YFDataException(f"Yahoo API requires curl_cffi session not {type(session)}. Solution: stop setting session, let YF handle.")
|
||||
|
||||
with self._cookie_lock:
|
||||
self._session = session
|
||||
if self._proxy is not None:
|
||||
self._session.proxies = self._proxy
|
||||
|
||||
def _set_proxy(self, proxy=None):
|
||||
with self._cookie_lock:
|
||||
if proxy is not None:
|
||||
proxy = {'http': proxy, 'https': proxy} if isinstance(proxy, str) else proxy
|
||||
else:
|
||||
proxy = {}
|
||||
self._proxy = proxy
|
||||
self._session.proxies = proxy
|
||||
|
||||
def _set_cookie_strategy(self, strategy, have_lock=False):
|
||||
if strategy == self._cookie_strategy:
|
||||
@@ -116,83 +137,83 @@ class YfData(metaclass=SingletonMeta):
|
||||
if not have_lock:
|
||||
self._cookie_lock.release()
|
||||
|
||||
def _save_session_cookies(self):
|
||||
try:
|
||||
cache.get_cookie_cache().store('csrf', self._session.cookies)
|
||||
except Exception:
|
||||
@utils.log_indent_decorator
|
||||
def _save_cookie_curlCffi(self):
|
||||
if self._session is None:
|
||||
return False
|
||||
cookies = self._session.cookies.jar._cookies
|
||||
if len(cookies) == 0:
|
||||
return False
|
||||
yh_domains = [k for k in cookies.keys() if 'yahoo' in k]
|
||||
if len(yh_domains) > 1:
|
||||
# Possible when cookie fetched with CSRF method. Discard consent cookie.
|
||||
yh_domains = [k for k in yh_domains if 'consent' not in k]
|
||||
if len(yh_domains) > 1:
|
||||
utils.get_yf_logger().debug(f'Multiple Yahoo cookies, not sure which to cache: {yh_domains}')
|
||||
return False
|
||||
if len(yh_domains) == 0:
|
||||
return False
|
||||
yh_domain = yh_domains[0]
|
||||
yh_cookie = {yh_domain: cookies[yh_domain]}
|
||||
cache.get_cookie_cache().store('curlCffi', yh_cookie)
|
||||
return True
|
||||
|
||||
def _load_session_cookies(self):
|
||||
cookie_dict = cache.get_cookie_cache().lookup('csrf')
|
||||
if cookie_dict is None:
|
||||
@utils.log_indent_decorator
|
||||
def _load_cookie_curlCffi(self):
|
||||
if self._session is None:
|
||||
return False
|
||||
# Periodically refresh, 24 hours seems fair.
|
||||
if cookie_dict['age'] > datetime.timedelta(days=1):
|
||||
cookie_dict = cache.get_cookie_cache().lookup('curlCffi')
|
||||
if cookie_dict is None or len(cookie_dict) == 0:
|
||||
return False
|
||||
self._session.cookies.update(cookie_dict['cookie'])
|
||||
utils.get_yf_logger().debug('loaded persistent cookie')
|
||||
|
||||
def _save_cookie_basic(self, cookie):
|
||||
try:
|
||||
cache.get_cookie_cache().store('basic', cookie)
|
||||
except Exception:
|
||||
cookies = cookie_dict['cookie']
|
||||
domain = list(cookies.keys())[0]
|
||||
cookie = cookies[domain]['/']['A3']
|
||||
expiry_ts = cookie.expires
|
||||
if expiry_ts > 2e9:
|
||||
# convert ms to s
|
||||
expiry_ts //= 1e3
|
||||
expiry_dt = datetime.datetime.fromtimestamp(expiry_ts, tz=datetime.timezone.utc)
|
||||
expired = expiry_dt < datetime.datetime.now(datetime.timezone.utc)
|
||||
if expired:
|
||||
utils.get_yf_logger().debug('cached cookie expired')
|
||||
return False
|
||||
self._session.cookies.jar._cookies.update(cookies)
|
||||
self._cookie = cookie
|
||||
return True
|
||||
def _load_cookie_basic(self):
|
||||
cookie_dict = cache.get_cookie_cache().lookup('basic')
|
||||
if cookie_dict is None:
|
||||
return None
|
||||
# Periodically refresh, 24 hours seems fair.
|
||||
if cookie_dict['age'] > datetime.timedelta(days=1):
|
||||
return None
|
||||
utils.get_yf_logger().debug('loaded persistent cookie')
|
||||
return cookie_dict['cookie']
|
||||
|
||||
def _get_cookie_basic(self, proxy=None, timeout=30):
|
||||
@utils.log_indent_decorator
|
||||
def _get_cookie_basic(self, timeout=30):
|
||||
if self._cookie is not None:
|
||||
utils.get_yf_logger().debug('reusing cookie')
|
||||
return self._cookie
|
||||
|
||||
self._cookie = self._load_cookie_basic()
|
||||
if self._cookie is not None:
|
||||
return self._cookie
|
||||
return True
|
||||
elif self._load_cookie_curlCffi():
|
||||
utils.get_yf_logger().debug('reusing persistent cookie')
|
||||
return True
|
||||
|
||||
# To avoid infinite recursion, do NOT use self.get()
|
||||
# - 'allow_redirects' copied from @psychoz971 solution - does it help USA?
|
||||
response = self._session.get(
|
||||
url='https://fc.yahoo.com',
|
||||
headers=self.user_agent_headers,
|
||||
proxies=proxy,
|
||||
timeout=timeout,
|
||||
allow_redirects=True)
|
||||
try:
|
||||
self._session.get(
|
||||
url='https://fc.yahoo.com',
|
||||
timeout=timeout,
|
||||
allow_redirects=True)
|
||||
except requests.exceptions.DNSError:
|
||||
# Possible because url on some privacy/ad blocklists
|
||||
return False
|
||||
self._save_cookie_curlCffi()
|
||||
return True
|
||||
|
||||
if not response.cookies:
|
||||
utils.get_yf_logger().debug("response.cookies = None")
|
||||
return None
|
||||
self._cookie = list(response.cookies)[0]
|
||||
if self._cookie == '':
|
||||
utils.get_yf_logger().debug("list(response.cookies)[0] = ''")
|
||||
return None
|
||||
self._save_cookie_basic(self._cookie)
|
||||
utils.get_yf_logger().debug(f"fetched basic cookie = {self._cookie}")
|
||||
return self._cookie
|
||||
|
||||
def _get_crumb_basic(self, proxy=None, timeout=30):
|
||||
@utils.log_indent_decorator
|
||||
def _get_crumb_basic(self, timeout=30):
|
||||
if self._crumb is not None:
|
||||
utils.get_yf_logger().debug('reusing crumb')
|
||||
return self._crumb
|
||||
|
||||
cookie = self._get_cookie_basic()
|
||||
if cookie is None:
|
||||
if not self._get_cookie_basic():
|
||||
return None
|
||||
|
||||
# - 'allow_redirects' copied from @psychoz971 solution - does it help USA?
|
||||
get_args = {
|
||||
'url': "https://query1.finance.yahoo.com/v1/test/getcrumb",
|
||||
'headers': self.user_agent_headers,
|
||||
'cookies': {cookie.name: cookie.value},
|
||||
'proxies': proxy,
|
||||
'timeout': timeout,
|
||||
'allow_redirects': True
|
||||
}
|
||||
@@ -202,6 +223,10 @@ class YfData(metaclass=SingletonMeta):
|
||||
else:
|
||||
crumb_response = self._session.get(**get_args)
|
||||
self._crumb = crumb_response.text
|
||||
if crumb_response.status_code == 429 or "Too Many Requests" in self._crumb:
|
||||
utils.get_yf_logger().debug(f"Didn't receive crumb {self._crumb}")
|
||||
raise YFRateLimitError()
|
||||
|
||||
if self._crumb is None or '<html>' in self._crumb:
|
||||
utils.get_yf_logger().debug("Didn't receive crumb")
|
||||
return None
|
||||
@@ -210,32 +235,36 @@ class YfData(metaclass=SingletonMeta):
|
||||
return self._crumb
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _get_cookie_and_crumb_basic(self, proxy, timeout):
|
||||
cookie = self._get_cookie_basic(proxy, timeout)
|
||||
crumb = self._get_crumb_basic(proxy, timeout)
|
||||
return cookie, crumb
|
||||
def _get_cookie_and_crumb_basic(self, timeout):
|
||||
if not self._get_cookie_basic(timeout):
|
||||
return None
|
||||
return self._get_crumb_basic(timeout)
|
||||
|
||||
def _get_cookie_csrf(self, proxy, timeout):
|
||||
@utils.log_indent_decorator
|
||||
def _get_cookie_csrf(self, timeout):
|
||||
if self._cookie is not None:
|
||||
utils.get_yf_logger().debug('reusing cookie')
|
||||
return True
|
||||
|
||||
elif self._load_session_cookies():
|
||||
elif self._load_cookie_curlCffi():
|
||||
utils.get_yf_logger().debug('reusing persistent cookie')
|
||||
self._cookie = True
|
||||
return True
|
||||
|
||||
base_args = {
|
||||
'headers': self.user_agent_headers,
|
||||
'proxies': proxy,
|
||||
'timeout': timeout}
|
||||
|
||||
get_args = {**base_args, 'url': 'https://guce.yahoo.com/consent'}
|
||||
if self._session_is_caching:
|
||||
get_args['expire_after'] = self._expire_after
|
||||
response = self._session.get(**get_args)
|
||||
else:
|
||||
response = self._session.get(**get_args)
|
||||
try:
|
||||
if self._session_is_caching:
|
||||
get_args['expire_after'] = self._expire_after
|
||||
response = self._session.get(**get_args)
|
||||
else:
|
||||
response = self._session.get(**get_args)
|
||||
except requests.exceptions.ChunkedEncodingError:
|
||||
# No idea why happens, but handle nicely so can switch to other cookie method.
|
||||
utils.get_yf_logger().debug('_get_cookie_csrf() encountering requests.exceptions.ChunkedEncodingError, aborting')
|
||||
return False
|
||||
|
||||
soup = BeautifulSoup(response.content, 'html.parser')
|
||||
csrfTokenInput = soup.find('input', attrs={'name': 'csrfToken'})
|
||||
@@ -264,34 +293,36 @@ class YfData(metaclass=SingletonMeta):
|
||||
get_args = {**base_args,
|
||||
'url': f'https://guce.yahoo.com/copyConsent?sessionId={sessionId}',
|
||||
'data': data}
|
||||
if self._session_is_caching:
|
||||
post_args['expire_after'] = self._expire_after
|
||||
get_args['expire_after'] = self._expire_after
|
||||
self._session.post(**post_args)
|
||||
self._session.get(**get_args)
|
||||
else:
|
||||
self._session.post(**post_args)
|
||||
self._session.get(**get_args)
|
||||
try:
|
||||
if self._session_is_caching:
|
||||
post_args['expire_after'] = self._expire_after
|
||||
get_args['expire_after'] = self._expire_after
|
||||
self._session.post(**post_args)
|
||||
self._session.get(**get_args)
|
||||
else:
|
||||
self._session.post(**post_args)
|
||||
self._session.get(**get_args)
|
||||
except requests.exceptions.ChunkedEncodingError:
|
||||
# No idea why happens, but handle nicely so can switch to other cookie method.
|
||||
utils.get_yf_logger().debug('_get_cookie_csrf() encountering requests.exceptions.ChunkedEncodingError, aborting')
|
||||
self._cookie = True
|
||||
self._save_session_cookies()
|
||||
self._save_cookie_curlCffi()
|
||||
return True
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _get_crumb_csrf(self, proxy=None, timeout=30):
|
||||
def _get_crumb_csrf(self, timeout=30):
|
||||
# Credit goes to @bot-unit #1729
|
||||
|
||||
if self._crumb is not None:
|
||||
utils.get_yf_logger().debug('reusing crumb')
|
||||
return self._crumb
|
||||
|
||||
if not self._get_cookie_csrf(proxy, timeout):
|
||||
if not self._get_cookie_csrf(timeout):
|
||||
# This cookie stored in session
|
||||
return None
|
||||
|
||||
get_args = {
|
||||
'url': 'https://query2.finance.yahoo.com/v1/test/getcrumb',
|
||||
'headers': self.user_agent_headers,
|
||||
'proxies': proxy,
|
||||
'timeout': timeout}
|
||||
if self._session_is_caching:
|
||||
get_args['expire_after'] = self._expire_after
|
||||
@@ -300,6 +331,10 @@ class YfData(metaclass=SingletonMeta):
|
||||
r = self._session.get(**get_args)
|
||||
self._crumb = r.text
|
||||
|
||||
if r.status_code == 429 or "Too Many Requests" in self._crumb:
|
||||
utils.get_yf_logger().debug(f"Didn't receive crumb {self._crumb}")
|
||||
raise YFRateLimitError()
|
||||
|
||||
if self._crumb is None or '<html>' in self._crumb or self._crumb == '':
|
||||
utils.get_yf_logger().debug("Didn't receive crumb")
|
||||
return None
|
||||
@@ -308,8 +343,8 @@ class YfData(metaclass=SingletonMeta):
|
||||
return self._crumb
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _get_cookie_and_crumb(self, proxy=None, timeout=30):
|
||||
cookie, crumb, strategy = None, None, None
|
||||
def _get_cookie_and_crumb(self, timeout=30):
|
||||
crumb, strategy = None, None
|
||||
|
||||
utils.get_yf_logger().debug(f"cookie_mode = '{self._cookie_strategy}'")
|
||||
|
||||
@@ -319,27 +354,27 @@ class YfData(metaclass=SingletonMeta):
|
||||
if crumb is None:
|
||||
# Fail
|
||||
self._set_cookie_strategy('basic', have_lock=True)
|
||||
cookie, crumb = self._get_cookie_and_crumb_basic(proxy, timeout)
|
||||
crumb = self._get_cookie_and_crumb_basic(timeout)
|
||||
else:
|
||||
# Fallback strategy
|
||||
cookie, crumb = self._get_cookie_and_crumb_basic(proxy, timeout)
|
||||
if cookie is None or crumb is None:
|
||||
crumb = self._get_cookie_and_crumb_basic(timeout)
|
||||
if crumb is None:
|
||||
# Fail
|
||||
self._set_cookie_strategy('csrf', have_lock=True)
|
||||
crumb = self._get_crumb_csrf()
|
||||
strategy = self._cookie_strategy
|
||||
return cookie, crumb, strategy
|
||||
return crumb, strategy
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def get(self, url, user_agent_headers=None, params=None, proxy=None, timeout=30):
|
||||
return self._make_request(url, request_method = self._session.get, user_agent_headers=user_agent_headers, params=params, proxy=proxy, timeout=timeout)
|
||||
|
||||
def get(self, url, params=None, timeout=30):
|
||||
return self._make_request(url, request_method = self._session.get, params=params, timeout=timeout)
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def post(self, url, body, user_agent_headers=None, params=None, proxy=None, timeout=30):
|
||||
return self._make_request(url, request_method = self._session.post, user_agent_headers=user_agent_headers, body=body, params=params, proxy=proxy, timeout=timeout)
|
||||
|
||||
def post(self, url, body, params=None, timeout=30):
|
||||
return self._make_request(url, request_method = self._session.post, body=body, params=params, timeout=timeout)
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _make_request(self, url, request_method, user_agent_headers=None, body=None, params=None, proxy=None, timeout=30):
|
||||
def _make_request(self, url, request_method, body=None, params=None, timeout=30):
|
||||
# Important: treat input arguments as immutable.
|
||||
|
||||
if len(url) > 200:
|
||||
@@ -347,36 +382,27 @@ class YfData(metaclass=SingletonMeta):
|
||||
else:
|
||||
utils.get_yf_logger().debug(f'url={url}')
|
||||
utils.get_yf_logger().debug(f'params={params}')
|
||||
proxy = self._get_proxy(proxy)
|
||||
|
||||
if params is None:
|
||||
params = {}
|
||||
if 'crumb' in params:
|
||||
raise Exception("Don't manually add 'crumb' to params dict, let data.py handle it")
|
||||
|
||||
cookie, crumb, strategy = self._get_cookie_and_crumb()
|
||||
crumb, strategy = self._get_cookie_and_crumb()
|
||||
if crumb is not None:
|
||||
crumbs = {'crumb': crumb}
|
||||
else:
|
||||
crumbs = {}
|
||||
if strategy == 'basic' and cookie is not None:
|
||||
# Basic cookie strategy adds cookie to GET parameters
|
||||
cookies = {cookie.name: cookie.value}
|
||||
else:
|
||||
cookies = None
|
||||
|
||||
request_args = {
|
||||
'url': url,
|
||||
'params': {**params, **crumbs},
|
||||
'cookies': cookies,
|
||||
'proxies': proxy,
|
||||
'timeout': timeout,
|
||||
'headers': user_agent_headers or self.user_agent_headers
|
||||
'timeout': timeout
|
||||
}
|
||||
|
||||
if body:
|
||||
request_args['json'] = body
|
||||
|
||||
|
||||
response = request_method(**request_args)
|
||||
utils.get_yf_logger().debug(f'response code={response.status_code}')
|
||||
if response.status_code >= 400:
|
||||
@@ -385,10 +411,8 @@ class YfData(metaclass=SingletonMeta):
|
||||
self._set_cookie_strategy('csrf')
|
||||
else:
|
||||
self._set_cookie_strategy('basic')
|
||||
cookie, crumb, strategy = self._get_cookie_and_crumb(proxy, timeout)
|
||||
crumb, strategy = self._get_cookie_and_crumb(timeout)
|
||||
request_args['params']['crumb'] = crumb
|
||||
if strategy == 'basic':
|
||||
request_args['cookies'] = {cookie.name: cookie.value}
|
||||
response = request_method(**request_args)
|
||||
utils.get_yf_logger().debug(f'response code={response.status_code}')
|
||||
|
||||
@@ -400,19 +424,11 @@ class YfData(metaclass=SingletonMeta):
|
||||
|
||||
@lru_cache_freezeargs
|
||||
@lru_cache(maxsize=cache_maxsize)
|
||||
def cache_get(self, url, user_agent_headers=None, params=None, proxy=None, timeout=30):
|
||||
return self.get(url, user_agent_headers, params, proxy, timeout)
|
||||
def cache_get(self, url, params=None, timeout=30):
|
||||
return self.get(url, params, timeout)
|
||||
|
||||
def _get_proxy(self, proxy):
|
||||
# setup proxy in requests format
|
||||
if proxy is not None:
|
||||
if isinstance(proxy, (dict, frozendict)) and "https" in proxy:
|
||||
proxy = proxy["https"]
|
||||
proxy = {"https": proxy}
|
||||
return proxy
|
||||
|
||||
def get_raw_json(self, url, user_agent_headers=None, params=None, proxy=None, timeout=30):
|
||||
def get_raw_json(self, url, params=None, timeout=30):
|
||||
utils.get_yf_logger().debug(f'get_raw_json(): {url}')
|
||||
response = self.get(url, user_agent_headers=user_agent_headers, params=params, proxy=proxy, timeout=timeout)
|
||||
response = self.get(url, params=params, timeout=timeout)
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
return response.json()
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from ..ticker import Ticker
|
||||
from ..const import _QUERY1_URL_
|
||||
from ..data import YfData
|
||||
from typing import Dict, List, Optional
|
||||
import pandas as _pd
|
||||
from typing import Dict, List, Optional
|
||||
import warnings
|
||||
|
||||
from ..const import _QUERY1_URL_, _SENTINEL_
|
||||
from ..data import YfData
|
||||
from ..ticker import Ticker
|
||||
|
||||
_QUERY_URL_ = f'{_QUERY1_URL_}/v1/finance'
|
||||
|
||||
@@ -13,20 +15,21 @@ class Domain(ABC):
|
||||
and methods for fetching and parsing data. Derived classes must implement the `_fetch_and_parse()` method.
|
||||
"""
|
||||
|
||||
def __init__(self, key: str, session=None, proxy=None):
|
||||
def __init__(self, key: str, session=None, proxy=_SENTINEL_):
|
||||
"""
|
||||
Initializes the Domain object with a key, session, and proxy.
|
||||
|
||||
Args:
|
||||
key (str): Unique key identifying the domain entity.
|
||||
session (Optional[requests.Session]): Session object for HTTP requests. Defaults to None.
|
||||
proxy (Optional[Dict]): Proxy settings. Defaults to None.
|
||||
"""
|
||||
self._key: str = key
|
||||
self.proxy = proxy
|
||||
self.session = session
|
||||
self._data: YfData = YfData(session=session)
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
self._name: Optional[str] = None
|
||||
self._symbol: Optional[str] = None
|
||||
self._overview: Optional[Dict] = None
|
||||
@@ -109,19 +112,18 @@ class Domain(ABC):
|
||||
self._ensure_fetched(self._research_reports)
|
||||
return self._research_reports
|
||||
|
||||
def _fetch(self, query_url, proxy) -> Dict:
|
||||
def _fetch(self, query_url) -> Dict:
|
||||
"""
|
||||
Fetches data from the given query URL.
|
||||
|
||||
Args:
|
||||
query_url (str): The URL used for the data query.
|
||||
proxy (Dict): Proxy settings for the request.
|
||||
|
||||
Returns:
|
||||
Dict: The JSON response data from the request.
|
||||
"""
|
||||
params_dict = {"formatted": "true", "withReturns": "true", "lang": "en-US", "region": "US"}
|
||||
result = self._data.get_raw_json(query_url, user_agent_headers=self._data.user_agent_headers, params=params_dict, proxy=proxy)
|
||||
result = self._data.get_raw_json(query_url, params=params_dict)
|
||||
return result
|
||||
|
||||
def _parse_and_assign_common(self, data) -> None:
|
||||
@@ -194,4 +196,4 @@ class Domain(ABC):
|
||||
attribute: The attribute to check and potentially fetch.
|
||||
"""
|
||||
if attribute is None:
|
||||
self._fetch_and_parse()
|
||||
self._fetch_and_parse()
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
from __future__ import print_function
|
||||
from typing import Dict, Optional
|
||||
|
||||
import pandas as _pd
|
||||
from typing import Dict, Optional
|
||||
import warnings
|
||||
|
||||
from .. import utils
|
||||
from ..const import _SENTINEL_
|
||||
from ..data import YfData
|
||||
|
||||
from .domain import Domain, _QUERY_URL_
|
||||
from .. import utils
|
||||
|
||||
class Industry(Domain):
|
||||
"""
|
||||
Represents an industry within a sector.
|
||||
"""
|
||||
|
||||
def __init__(self, key, session=None, proxy=None):
|
||||
def __init__(self, key, session=None, proxy=_SENTINEL_):
|
||||
"""
|
||||
Args:
|
||||
key (str): The key identifier for the industry.
|
||||
session (optional): The session to use for requests.
|
||||
proxy (optional): The proxy to use for requests.
|
||||
"""
|
||||
super(Industry, self).__init__(key, session, proxy)
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
YfData(proxy=proxy)
|
||||
YfData(session=session)
|
||||
super(Industry, self).__init__(key, session)
|
||||
self._query_url = f'{_QUERY_URL_}/industries/{self._key}'
|
||||
|
||||
self._sector_key = None
|
||||
@@ -129,7 +136,7 @@ class Industry(Domain):
|
||||
result = None
|
||||
|
||||
try:
|
||||
result = self._fetch(self._query_url, self.proxy)
|
||||
result = self._fetch(self._query_url)
|
||||
data = result['data']
|
||||
self._parse_and_assign_common(data)
|
||||
|
||||
@@ -145,4 +152,4 @@ class Industry(Domain):
|
||||
logger.debug("Got response: ")
|
||||
logger.debug("-------------")
|
||||
logger.debug(f" {result}")
|
||||
logger.debug("-------------")
|
||||
logger.debug("-------------")
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
import datetime as dt
|
||||
|
||||
from ..data import YfData
|
||||
from ..data import utils
|
||||
from ..const import _QUERY1_URL_
|
||||
import json as _json
|
||||
import warnings
|
||||
|
||||
class Market():
|
||||
def __init__(self, market:'str', session=None, proxy=None, timeout=30):
|
||||
from ..const import _QUERY1_URL_, _SENTINEL_
|
||||
from ..data import utils, YfData
|
||||
|
||||
class Market:
|
||||
def __init__(self, market:'str', session=None, proxy=_SENTINEL_, timeout=30):
|
||||
self.market = market
|
||||
self.session = session
|
||||
self.proxy = proxy
|
||||
self.timeout = timeout
|
||||
|
||||
self._data = YfData(session=self.session)
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
self._logger = utils.get_yf_logger()
|
||||
|
||||
self._status = None
|
||||
self._summary = None
|
||||
|
||||
def _fetch_json(self, url, params):
|
||||
data = self._data.cache_get(url=url, params=params, proxy=self.proxy, timeout=self.timeout)
|
||||
data = self._data.cache_get(url=url, params=params, timeout=self.timeout)
|
||||
if data is None or "Will be right back" in data.text:
|
||||
raise RuntimeError("*** YAHOO! FINANCE IS CURRENTLY DOWN! ***\n"
|
||||
"Our engineers are working quickly to resolve "
|
||||
@@ -52,7 +55,7 @@ class Market():
|
||||
status_params = {
|
||||
"formatted": True,
|
||||
"key": "finance",
|
||||
"lang": "en-GB",
|
||||
"lang": "en-US",
|
||||
"market": self.market
|
||||
}
|
||||
|
||||
@@ -73,11 +76,11 @@ class Market():
|
||||
self._status['timezone'] = self._status['timezone'][0]
|
||||
del self._status['time'] # redundant
|
||||
try:
|
||||
self._status.update(
|
||||
open = dt.datetime.fromisoformat(self._status["open"]),
|
||||
close = dt.datetime.fromisoformat(self._status["close"]),
|
||||
tz = dt.timezone(self._status["timezone"]["gmtoffset"], self._status["timezone"]["short"])
|
||||
)
|
||||
self._status.update({
|
||||
"open": dt.datetime.fromisoformat(self._status["open"]),
|
||||
"close": dt.datetime.fromisoformat(self._status["close"]),
|
||||
"tz": dt.timezone(dt.timedelta(hours=int(self._status["timezone"]["gmtoffset"]))/1000, self._status["timezone"]["short"])
|
||||
})
|
||||
except Exception as e:
|
||||
self._logger.error(f"{self.market}: Failed to update market status")
|
||||
self._logger.debug(f"{type(e)}: {e}")
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from __future__ import print_function
|
||||
from typing import Dict, Optional
|
||||
from ..utils import dynamic_docstring, generate_list_table_from_dict
|
||||
from ..const import SECTOR_INDUSTY_MAPPING
|
||||
|
||||
import pandas as _pd
|
||||
from typing import Dict, Optional
|
||||
import warnings
|
||||
|
||||
from ..const import SECTOR_INDUSTY_MAPPING, _SENTINEL_
|
||||
from ..data import YfData
|
||||
from ..utils import dynamic_docstring, generate_list_table_from_dict, get_yf_logger
|
||||
|
||||
from .domain import Domain, _QUERY_URL_
|
||||
from .. import utils
|
||||
|
||||
class Sector(Domain):
|
||||
"""
|
||||
@@ -14,7 +16,7 @@ class Sector(Domain):
|
||||
such as top ETFs, top mutual funds, and industry data.
|
||||
"""
|
||||
|
||||
def __init__(self, key, session=None, proxy=None):
|
||||
def __init__(self, key, session=None, proxy=_SENTINEL_):
|
||||
"""
|
||||
Args:
|
||||
key (str): The key representing the sector.
|
||||
@@ -26,7 +28,11 @@ class Sector(Domain):
|
||||
:attr:`Sector.industries <yfinance.Sector.industries>`
|
||||
Map of sector and industry
|
||||
"""
|
||||
super(Sector, self).__init__(key, session, proxy)
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
YfData(session=session, proxy=proxy)
|
||||
|
||||
super(Sector, self).__init__(key, session)
|
||||
self._query_url: str = f'{_QUERY_URL_}/sectors/{self._key}'
|
||||
self._top_etfs: Optional[Dict] = None
|
||||
self._top_mutual_funds: Optional[Dict] = None
|
||||
@@ -133,7 +139,7 @@ class Sector(Domain):
|
||||
result = None
|
||||
|
||||
try:
|
||||
result = self._fetch(self._query_url, self.proxy)
|
||||
result = self._fetch(self._query_url)
|
||||
data = result['data']
|
||||
self._parse_and_assign_common(data)
|
||||
|
||||
@@ -142,9 +148,9 @@ class Sector(Domain):
|
||||
self._industries = self._parse_industries(data.get('industries', {}))
|
||||
|
||||
except Exception as e:
|
||||
logger = utils.get_yf_logger()
|
||||
logger = get_yf_logger()
|
||||
logger.error(f"Failed to get sector data for '{self._key}' reason: {e}")
|
||||
logger.debug("Got response: ")
|
||||
logger.debug("-------------")
|
||||
logger.debug(f" {result}")
|
||||
logger.debug("-------------")
|
||||
logger.debug("-------------")
|
||||
|
||||
@@ -45,7 +45,7 @@ class YFInvalidPeriodError(YFException):
|
||||
self.invalid_period = invalid_period
|
||||
self.valid_ranges = valid_ranges
|
||||
super().__init__(f"{self.ticker}: Period '{invalid_period}' is invalid, "
|
||||
f"must be of the format {valid_ranges}, etc.")
|
||||
f"must be one of: {valid_ranges}")
|
||||
|
||||
|
||||
class YFRateLimitError(YFException):
|
||||
|
||||
335
yfinance/live.py
Normal file
@@ -0,0 +1,335 @@
|
||||
import asyncio
|
||||
import base64
|
||||
import json
|
||||
from typing import List, Optional, Callable, Union
|
||||
|
||||
from websockets.sync.client import connect as sync_connect
|
||||
from websockets.asyncio.client import connect as async_connect
|
||||
|
||||
from yfinance import utils
|
||||
from yfinance.pricing_pb2 import PricingData
|
||||
from google.protobuf.json_format import MessageToDict
|
||||
|
||||
|
||||
class BaseWebSocket:
|
||||
def __init__(self, url: str = "wss://streamer.finance.yahoo.com/?version=2", verbose=True):
|
||||
self.url = url
|
||||
self.verbose = verbose
|
||||
self.logger = utils.get_yf_logger()
|
||||
self._ws = None
|
||||
self._subscriptions = set()
|
||||
self._subscription_interval = 15 # seconds
|
||||
|
||||
def _decode_message(self, base64_message: str) -> dict:
|
||||
try:
|
||||
decoded_bytes = base64.b64decode(base64_message)
|
||||
pricing_data = PricingData()
|
||||
pricing_data.ParseFromString(decoded_bytes)
|
||||
return MessageToDict(pricing_data, preserving_proto_field_name=True)
|
||||
except Exception as e:
|
||||
self.logger.error("Failed to decode message: %s", e, exc_info=True)
|
||||
if self.verbose:
|
||||
print("Failed to decode message: %s", e)
|
||||
return {
|
||||
'error': str(e),
|
||||
'raw_base64': base64_message
|
||||
}
|
||||
|
||||
|
||||
class AsyncWebSocket(BaseWebSocket):
|
||||
"""
|
||||
Asynchronous WebSocket client for streaming real time pricing data.
|
||||
"""
|
||||
|
||||
def __init__(self, url: str = "wss://streamer.finance.yahoo.com/?version=2", verbose=True):
|
||||
"""
|
||||
Initialize the AsyncWebSocket client.
|
||||
|
||||
Args:
|
||||
url (str): The WebSocket server URL. Defaults to Yahoo Finance's WebSocket URL.
|
||||
verbose (bool): Flag to enable or disable print statements. Defaults to True.
|
||||
"""
|
||||
super().__init__(url, verbose)
|
||||
self._message_handler = None # Callable to handle messages
|
||||
self._heartbeat_task = None # Task to send heartbeat subscribe
|
||||
|
||||
async def _connect(self):
|
||||
try:
|
||||
if self._ws is None:
|
||||
self._ws = await async_connect(self.url)
|
||||
self.logger.info("Connected to WebSocket.")
|
||||
if self.verbose:
|
||||
print("Connected to WebSocket.")
|
||||
except Exception as e:
|
||||
self.logger.error("Failed to connect to WebSocket: %s", e, exc_info=True)
|
||||
if self.verbose:
|
||||
print(f"Failed to connect to WebSocket: {e}")
|
||||
self._ws = None
|
||||
raise
|
||||
|
||||
async def _periodic_subscribe(self):
|
||||
while True:
|
||||
try:
|
||||
await asyncio.sleep(self._subscription_interval)
|
||||
|
||||
if self._subscriptions:
|
||||
message = {"subscribe": list(self._subscriptions)}
|
||||
await self._ws.send(json.dumps(message))
|
||||
|
||||
if self.verbose:
|
||||
print(f"Heartbeat subscription sent for symbols: {self._subscriptions}")
|
||||
except Exception as e:
|
||||
self.logger.error("Error in heartbeat subscription: %s", e, exc_info=True)
|
||||
if self.verbose:
|
||||
print(f"Error in heartbeat subscription: {e}")
|
||||
break
|
||||
|
||||
async def subscribe(self, symbols: Union[str, List[str]]):
|
||||
"""
|
||||
Subscribe to a stock symbol or a list of stock symbols.
|
||||
|
||||
Args:
|
||||
symbols (Union[str, List[str]]): Stock symbol(s) to subscribe to.
|
||||
"""
|
||||
await self._connect()
|
||||
|
||||
if isinstance(symbols, str):
|
||||
symbols = [symbols]
|
||||
|
||||
self._subscriptions.update(symbols)
|
||||
|
||||
message = {"subscribe": list(self._subscriptions)}
|
||||
await self._ws.send(json.dumps(message))
|
||||
|
||||
# Start heartbeat subscription task
|
||||
if self._heartbeat_task is None:
|
||||
self._heartbeat_task = asyncio.create_task(self._periodic_subscribe())
|
||||
|
||||
self.logger.info(f"Subscribed to symbols: {symbols}")
|
||||
if self.verbose:
|
||||
print(f"Subscribed to symbols: {symbols}")
|
||||
|
||||
async def unsubscribe(self, symbols: Union[str, List[str]]):
|
||||
"""
|
||||
Unsubscribe from a stock symbol or a list of stock symbols.
|
||||
|
||||
Args:
|
||||
symbols (Union[str, List[str]]): Stock symbol(s) to unsubscribe from.
|
||||
"""
|
||||
await self._connect()
|
||||
|
||||
if isinstance(symbols, str):
|
||||
symbols = [symbols]
|
||||
|
||||
self._subscriptions.difference_update(symbols)
|
||||
|
||||
message = {"unsubscribe": symbols}
|
||||
await self._ws.send(json.dumps(message))
|
||||
|
||||
self.logger.info(f"Unsubscribed from symbols: {symbols}")
|
||||
if self.verbose:
|
||||
print(f"Unsubscribed from symbols: {symbols}")
|
||||
|
||||
async def listen(self, message_handler=None):
|
||||
"""
|
||||
Start listening to messages from the WebSocket server.
|
||||
|
||||
Args:
|
||||
message_handler (Optional[Callable[[dict], None]]): Optional function to handle received messages.
|
||||
"""
|
||||
await self._connect()
|
||||
self._message_handler = message_handler
|
||||
|
||||
self.logger.info("Listening for messages...")
|
||||
if self.verbose:
|
||||
print("Listening for messages...")
|
||||
|
||||
# Start heartbeat subscription task
|
||||
if self._heartbeat_task is None:
|
||||
self._heartbeat_task = asyncio.create_task(self._periodic_subscribe())
|
||||
|
||||
while True:
|
||||
try:
|
||||
async for message in self._ws:
|
||||
message_json = json.loads(message)
|
||||
encoded_data = message_json.get("message", "")
|
||||
decoded_message = self._decode_message(encoded_data)
|
||||
|
||||
if self._message_handler:
|
||||
try:
|
||||
if asyncio.iscoroutinefunction(self._message_handler):
|
||||
await self._message_handler(decoded_message)
|
||||
else:
|
||||
self._message_handler(decoded_message)
|
||||
except Exception as handler_exception:
|
||||
self.logger.error("Error in message handler: %s", handler_exception, exc_info=True)
|
||||
if self.verbose:
|
||||
print("Error in message handler:", handler_exception)
|
||||
else:
|
||||
print(decoded_message)
|
||||
|
||||
except (KeyboardInterrupt, asyncio.CancelledError):
|
||||
self.logger.info("WebSocket listening interrupted. Closing connection...")
|
||||
if self.verbose:
|
||||
print("WebSocket listening interrupted. Closing connection...")
|
||||
await self.close()
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error("Error while listening to messages: %s", e, exc_info=True)
|
||||
if self.verbose:
|
||||
print("Error while listening to messages: %s", e)
|
||||
|
||||
# Attempt to reconnect if connection drops
|
||||
self.logger.info("Attempting to reconnect...")
|
||||
if self.verbose:
|
||||
print("Attempting to reconnect...")
|
||||
await asyncio.sleep(3) # backoff
|
||||
await self._connect()
|
||||
|
||||
async def close(self):
|
||||
"""Close the WebSocket connection."""
|
||||
if self._heartbeat_task:
|
||||
self._heartbeat_task.cancel()
|
||||
|
||||
if self._ws is not None: # and not self._ws.closed:
|
||||
await self._ws.close()
|
||||
self.logger.info("WebSocket connection closed.")
|
||||
if self.verbose:
|
||||
print("WebSocket connection closed.")
|
||||
|
||||
async def __aenter__(self):
|
||||
await self._connect()
|
||||
return self
|
||||
|
||||
async def __aexit__(self, exc_type, exc_value, traceback):
|
||||
await self.close()
|
||||
|
||||
|
||||
class WebSocket(BaseWebSocket):
|
||||
"""
|
||||
Synchronous WebSocket client for streaming real time pricing data.
|
||||
"""
|
||||
|
||||
def __init__(self, url: str = "wss://streamer.finance.yahoo.com/?version=2", verbose=True):
|
||||
"""
|
||||
Initialize the WebSocket client.
|
||||
|
||||
Args:
|
||||
url (str): The WebSocket server URL. Defaults to Yahoo Finance's WebSocket URL.
|
||||
verbose (bool): Flag to enable or disable print statements. Defaults to True.
|
||||
"""
|
||||
super().__init__(url, verbose)
|
||||
|
||||
def _connect(self):
|
||||
try:
|
||||
if self._ws is None:
|
||||
self._ws = sync_connect(self.url)
|
||||
self.logger.info("Connected to WebSocket.")
|
||||
if self.verbose:
|
||||
print("Connected to WebSocket.")
|
||||
except Exception as e:
|
||||
self.logger.error("Failed to connect to WebSocket: %s", e, exc_info=True)
|
||||
if self.verbose:
|
||||
print(f"Failed to connect to WebSocket: {e}")
|
||||
self._ws = None
|
||||
raise
|
||||
|
||||
def subscribe(self, symbols: Union[str, List[str]]):
|
||||
"""
|
||||
Subscribe to a stock symbol or a list of stock symbols.
|
||||
|
||||
Args:
|
||||
symbols (Union[str, List[str]]): Stock symbol(s) to subscribe to.
|
||||
"""
|
||||
self._connect()
|
||||
|
||||
if isinstance(symbols, str):
|
||||
symbols = [symbols]
|
||||
|
||||
self._subscriptions.update(symbols)
|
||||
|
||||
message = {"subscribe": list(self._subscriptions)}
|
||||
self._ws.send(json.dumps(message))
|
||||
|
||||
self.logger.info(f"Subscribed to symbols: {symbols}")
|
||||
if self.verbose:
|
||||
print(f"Subscribed to symbols: {symbols}")
|
||||
|
||||
def unsubscribe(self, symbols: Union[str, List[str]]):
|
||||
"""
|
||||
Unsubscribe from a stock symbol or a list of stock symbols.
|
||||
|
||||
Args:
|
||||
symbols (Union[str, List[str]]): Stock symbol(s) to unsubscribe from.
|
||||
"""
|
||||
self._connect()
|
||||
|
||||
if isinstance(symbols, str):
|
||||
symbols = [symbols]
|
||||
|
||||
self._subscriptions.difference_update(symbols)
|
||||
|
||||
message = {"unsubscribe": symbols}
|
||||
self._ws.send(json.dumps(message))
|
||||
|
||||
self.logger.info(f"Unsubscribed from symbols: {symbols}")
|
||||
if self.verbose:
|
||||
print(f"Unsubscribed from symbols: {symbols}")
|
||||
|
||||
def listen(self, message_handler: Optional[Callable[[dict], None]] = None):
|
||||
"""
|
||||
Start listening to messages from the WebSocket server.
|
||||
|
||||
Args:
|
||||
message_handler (Optional[Callable[[dict], None]]): Optional function to handle received messages.
|
||||
"""
|
||||
self._connect()
|
||||
|
||||
self.logger.info("Listening for messages...")
|
||||
if self.verbose:
|
||||
print("Listening for messages...")
|
||||
|
||||
while True:
|
||||
try:
|
||||
message = self._ws.recv()
|
||||
message_json = json.loads(message)
|
||||
encoded_data = message_json.get("message", "")
|
||||
decoded_message = self._decode_message(encoded_data)
|
||||
|
||||
if message_handler:
|
||||
try:
|
||||
message_handler(decoded_message)
|
||||
except Exception as handler_exception:
|
||||
self.logger.error("Error in message handler: %s", handler_exception, exc_info=True)
|
||||
if self.verbose:
|
||||
print("Error in message handler:", handler_exception)
|
||||
else:
|
||||
print(decoded_message)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
if self.verbose:
|
||||
print("Received keyboard interrupt.")
|
||||
self.close()
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error("Error while listening to messages: %s", e, exc_info=True)
|
||||
if self.verbose:
|
||||
print("Error while listening to messages: %s", e)
|
||||
break
|
||||
|
||||
def close(self):
|
||||
"""Close the WebSocket connection."""
|
||||
if self._ws is not None:
|
||||
self._ws.close()
|
||||
self.logger.info("WebSocket connection closed.")
|
||||
if self.verbose:
|
||||
print("WebSocket connection closed.")
|
||||
|
||||
def __enter__(self):
|
||||
self._connect()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
224
yfinance/lookup.py
Normal file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# yfinance - market data downloader
|
||||
# https://github.com/ranaroussi/yfinance
|
||||
#
|
||||
# Copyright 2017-2019 Ran Aroussi
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import json as _json
|
||||
import pandas as pd
|
||||
import warnings
|
||||
|
||||
from . import utils
|
||||
from .const import _QUERY1_URL_, _SENTINEL_
|
||||
from .data import YfData
|
||||
from .exceptions import YFException
|
||||
|
||||
LOOKUP_TYPES = ["all", "equity", "mutualfund", "etf", "index", "future", "currency", "cryptocurrency"]
|
||||
|
||||
|
||||
class Lookup:
|
||||
"""
|
||||
Fetches quote (ticker) lookups from Yahoo Finance.
|
||||
|
||||
:param query: The search query for financial data lookup.
|
||||
:type query: str
|
||||
:param session: Custom HTTP session for requests (default None).
|
||||
:param proxy: Proxy settings for requests (default None).
|
||||
:param timeout: Request timeout in seconds (default 30).
|
||||
:param raise_errors: Raise exceptions on error (default True).
|
||||
"""
|
||||
|
||||
def __init__(self, query: str, session=None, proxy=_SENTINEL_, timeout=30, raise_errors=True):
|
||||
self.session = session
|
||||
self._data = YfData(session=self.session)
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
self.query = query
|
||||
|
||||
self.timeout = timeout
|
||||
self.raise_errors = raise_errors
|
||||
|
||||
self._logger = utils.get_yf_logger()
|
||||
|
||||
self._cache = {}
|
||||
|
||||
def _fetch_lookup(self, lookup_type="all", count=25) -> dict:
|
||||
cache_key = (lookup_type, count)
|
||||
if cache_key in self._cache:
|
||||
return self._cache[cache_key]
|
||||
|
||||
url = f"{_QUERY1_URL_}/v1/finance/lookup"
|
||||
params = {
|
||||
"query": self.query,
|
||||
"type": lookup_type,
|
||||
"start": 0,
|
||||
"count": count,
|
||||
"formatted": False,
|
||||
"fetchPricingData": True,
|
||||
"lang": "en-US",
|
||||
"region": "US"
|
||||
}
|
||||
|
||||
self._logger.debug(f'GET Lookup for ticker ({self.query}) with parameters: {str(dict(params))}')
|
||||
|
||||
data = self._data.get(url=url, params=params, timeout=self.timeout)
|
||||
if data is None or "Will be right back" in data.text:
|
||||
raise RuntimeError("*** YAHOO! FINANCE IS CURRENTLY DOWN! ***\n"
|
||||
"Our engineers are working quickly to resolve "
|
||||
"the issue. Thank you for your patience.")
|
||||
try:
|
||||
data = data.json()
|
||||
except _json.JSONDecodeError:
|
||||
self._logger.error(f"{self.query}: Failed to retrieve lookup results and received faulty response instead.")
|
||||
data = {}
|
||||
|
||||
# Error returned
|
||||
if data.get("finance", {}).get("error", {}):
|
||||
raise YFException(data.get("finance", {}).get("error", {}))
|
||||
|
||||
self._cache[cache_key] = data
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def _parse_response(response: dict) -> pd.DataFrame:
|
||||
finance = response.get("finance", {})
|
||||
result = finance.get("result", [])
|
||||
result = result[0] if len(result) > 0 else {}
|
||||
documents = result.get("documents", [])
|
||||
df = pd.DataFrame(documents)
|
||||
if "symbol" not in df.columns:
|
||||
return pd.DataFrame()
|
||||
return df.set_index("symbol")
|
||||
|
||||
def _get_data(self, lookup_type: str, count: int = 25) -> pd.DataFrame:
|
||||
return self._parse_response(self._fetch_lookup(lookup_type, count))
|
||||
|
||||
def get_all(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns all available financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("all", count)
|
||||
|
||||
def get_stock(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns stock related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("equity", count)
|
||||
|
||||
def get_mutualfund(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns mutual funds related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("mutualfund", count)
|
||||
|
||||
def get_etf(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns ETFs related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("etf", count)
|
||||
|
||||
def get_index(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns Indices related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("index", count)
|
||||
|
||||
def get_future(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns Futures related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("future", count)
|
||||
|
||||
def get_currency(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns Currencies related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("currency", count)
|
||||
|
||||
def get_cryptocurrency(self, count=25) -> pd.DataFrame:
|
||||
"""
|
||||
Returns Cryptocurrencies related financial instruments.
|
||||
|
||||
:param count: The number of results to retrieve.
|
||||
:type count: int
|
||||
"""
|
||||
return self._get_data("cryptocurrency", count)
|
||||
|
||||
@property
|
||||
def all(self) -> pd.DataFrame:
|
||||
"""Returns all available financial instruments."""
|
||||
return self._get_data("all")
|
||||
|
||||
@property
|
||||
def stock(self) -> pd.DataFrame:
|
||||
"""Returns stock related financial instruments."""
|
||||
return self._get_data("equity")
|
||||
|
||||
@property
|
||||
def mutualfund(self) -> pd.DataFrame:
|
||||
"""Returns mutual funds related financial instruments."""
|
||||
return self._get_data("mutualfund")
|
||||
|
||||
@property
|
||||
def etf(self) -> pd.DataFrame:
|
||||
"""Returns ETFs related financial instruments."""
|
||||
return self._get_data("etf")
|
||||
|
||||
@property
|
||||
def index(self) -> pd.DataFrame:
|
||||
"""Returns Indices related financial instruments."""
|
||||
return self._get_data("index")
|
||||
|
||||
@property
|
||||
def future(self) -> pd.DataFrame:
|
||||
"""Returns Futures related financial instruments."""
|
||||
return self._get_data("future")
|
||||
|
||||
@property
|
||||
def currency(self) -> pd.DataFrame:
|
||||
"""Returns Currencies related financial instruments."""
|
||||
return self._get_data("currency")
|
||||
|
||||
@property
|
||||
def cryptocurrency(self) -> pd.DataFrame:
|
||||
"""Returns Cryptocurrencies related financial instruments."""
|
||||
return self._get_data("cryptocurrency")
|
||||
@@ -25,20 +25,22 @@ import logging
|
||||
import time as _time
|
||||
import traceback
|
||||
from typing import Union
|
||||
import warnings
|
||||
|
||||
import multitasking as _multitasking
|
||||
import pandas as _pd
|
||||
from curl_cffi import requests
|
||||
|
||||
from . import Ticker, utils
|
||||
from .data import YfData
|
||||
from . import shared
|
||||
|
||||
from .const import _SENTINEL_
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
ignore_tz=None, group_by='column', auto_adjust=True, back_adjust=False,
|
||||
repair=False, keepna=False, progress=True, period="max", interval="1d",
|
||||
prepost=False, proxy=None, rounding=False, timeout=10, session=None,
|
||||
ignore_tz=None, group_by='column', auto_adjust=None, back_adjust=False,
|
||||
repair=False, keepna=False, progress=True, period=None, interval="1d",
|
||||
prepost=False, proxy=_SENTINEL_, rounding=False, timeout=10, session=None,
|
||||
multi_level_index=True) -> Union[_pd.DataFrame, None]:
|
||||
"""
|
||||
Download yahoo tickers
|
||||
@@ -47,6 +49,7 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
List of tickers to download
|
||||
period : str
|
||||
Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
|
||||
Default: 1mo
|
||||
Either Use period parameter or use start and end
|
||||
interval : str
|
||||
Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
|
||||
@@ -79,8 +82,6 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
ignore_tz: bool
|
||||
When combining from different timezones, ignore that part of datetime.
|
||||
Default depends on interval. Intraday = False. Day+ = True.
|
||||
proxy: str
|
||||
Optional. Proxy server URL scheme. Default is None
|
||||
rounding: bool
|
||||
Optional. Round values to 2 decimal places?
|
||||
timeout: None or float
|
||||
@@ -92,6 +93,18 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
Optional. Always return a MultiIndex DataFrame? Default is True
|
||||
"""
|
||||
logger = utils.get_yf_logger()
|
||||
session = session or requests.Session(impersonate="chrome")
|
||||
|
||||
# Ensure data initialised with session.
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=3)
|
||||
YfData(proxy=proxy)
|
||||
YfData(session=session)
|
||||
|
||||
if auto_adjust is None:
|
||||
# Warn users that default has changed to True
|
||||
warnings.warn("YF.download() has changed argument auto_adjust default to True", FutureWarning, stacklevel=3)
|
||||
auto_adjust = True
|
||||
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
if threads:
|
||||
@@ -106,7 +119,7 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
|
||||
if ignore_tz is None:
|
||||
# Set default value depending on interval
|
||||
if interval[1:] in ['m', 'h']:
|
||||
if interval[-1] in ['m', 'h']:
|
||||
# Intraday
|
||||
ignore_tz = False
|
||||
else:
|
||||
@@ -122,7 +135,7 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
for ticker in tickers:
|
||||
if utils.is_isin(ticker):
|
||||
isin = ticker
|
||||
ticker = utils.get_ticker_by_isin(ticker, proxy, session=session)
|
||||
ticker = utils.get_ticker_by_isin(ticker)
|
||||
shared._ISINS[ticker] = isin
|
||||
_tickers_.append(ticker)
|
||||
|
||||
@@ -138,9 +151,6 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
shared._ERRORS = {}
|
||||
shared._TRACEBACKS = {}
|
||||
|
||||
# Ensure data initialised with session.
|
||||
YfData(session=session)
|
||||
|
||||
# download using threads
|
||||
if threads:
|
||||
if threads is True:
|
||||
@@ -151,7 +161,7 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
start=start, end=end, prepost=prepost,
|
||||
actions=actions, auto_adjust=auto_adjust,
|
||||
back_adjust=back_adjust, repair=repair, keepna=keepna,
|
||||
progress=(progress and i > 0), proxy=proxy,
|
||||
progress=(progress and i > 0),
|
||||
rounding=rounding, timeout=timeout)
|
||||
while len(shared._DFS) < len(tickers):
|
||||
_time.sleep(0.01)
|
||||
@@ -162,7 +172,6 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
start=start, end=end, prepost=prepost,
|
||||
actions=actions, auto_adjust=auto_adjust,
|
||||
back_adjust=back_adjust, repair=repair, keepna=keepna,
|
||||
proxy=proxy,
|
||||
rounding=rounding, timeout=timeout)
|
||||
if progress:
|
||||
shared._PROGRESS_BAR.animate()
|
||||
@@ -180,7 +189,7 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
errors = {}
|
||||
for ticker in shared._ERRORS:
|
||||
err = shared._ERRORS[ticker]
|
||||
err = err.replace(f'{ticker}', '%ticker%')
|
||||
err = err.replace(f'${ticker}: ', '')
|
||||
if err not in errors:
|
||||
errors[err] = [ticker]
|
||||
else:
|
||||
@@ -192,7 +201,7 @@ def download(tickers, start=None, end=None, actions=False, threads=True,
|
||||
tbs = {}
|
||||
for ticker in shared._TRACEBACKS:
|
||||
tb = shared._TRACEBACKS[ticker]
|
||||
tb = tb.replace(f'{ticker}', '%ticker%')
|
||||
tb = tb.replace(f'${ticker}: ', '')
|
||||
if tb not in tbs:
|
||||
tbs[tb] = [ticker]
|
||||
else:
|
||||
@@ -253,10 +262,10 @@ def _realign_dfs():
|
||||
def _download_one_threaded(ticker, start=None, end=None,
|
||||
auto_adjust=False, back_adjust=False, repair=False,
|
||||
actions=False, progress=True, period="max",
|
||||
interval="1d", prepost=False, proxy=None,
|
||||
interval="1d", prepost=False,
|
||||
keepna=False, rounding=False, timeout=10):
|
||||
_download_one(ticker, start, end, auto_adjust, back_adjust, repair,
|
||||
actions, period, interval, prepost, proxy, rounding,
|
||||
actions, period, interval, prepost, rounding,
|
||||
keepna, timeout)
|
||||
if progress:
|
||||
shared._PROGRESS_BAR.animate()
|
||||
@@ -265,7 +274,7 @@ def _download_one_threaded(ticker, start=None, end=None,
|
||||
def _download_one(ticker, start=None, end=None,
|
||||
auto_adjust=False, back_adjust=False, repair=False,
|
||||
actions=False, period="max", interval="1d",
|
||||
prepost=False, proxy=None, rounding=False,
|
||||
prepost=False, rounding=False,
|
||||
keepna=False, timeout=10):
|
||||
data = None
|
||||
try:
|
||||
@@ -273,7 +282,7 @@ def _download_one(ticker, start=None, end=None,
|
||||
period=period, interval=interval,
|
||||
start=start, end=end, prepost=prepost,
|
||||
actions=actions, auto_adjust=auto_adjust,
|
||||
back_adjust=back_adjust, repair=repair, proxy=proxy,
|
||||
back_adjust=back_adjust, repair=repair,
|
||||
rounding=rounding, keepna=keepna, timeout=timeout,
|
||||
raise_errors=True
|
||||
)
|
||||
|
||||
37
yfinance/pricing.proto
Normal file
@@ -0,0 +1,37 @@
|
||||
syntax = "proto3";
|
||||
|
||||
message PricingData {
|
||||
string id = 1;
|
||||
float price = 2;
|
||||
sint64 time = 3;
|
||||
string currency = 4;
|
||||
string exchange = 5;
|
||||
int32 quote_type = 6;
|
||||
int32 market_hours = 7;
|
||||
float change_percent = 8;
|
||||
sint64 day_volume = 9;
|
||||
float day_high = 10;
|
||||
float day_low = 11;
|
||||
float change = 12;
|
||||
string short_name = 13;
|
||||
sint64 expire_date = 14;
|
||||
float open_price = 15;
|
||||
float previous_close = 16;
|
||||
float strike_price = 17;
|
||||
string underlying_symbol = 18;
|
||||
sint64 open_interest = 19;
|
||||
sint64 options_type = 20;
|
||||
sint64 mini_option = 21;
|
||||
sint64 last_size = 22;
|
||||
float bid = 23;
|
||||
sint64 bid_size = 24;
|
||||
float ask = 25;
|
||||
sint64 ask_size = 26;
|
||||
sint64 price_hint = 27;
|
||||
sint64 vol_24hr = 28;
|
||||
sint64 vol_all_currencies = 29;
|
||||
string from_currency = 30;
|
||||
string last_market = 31;
|
||||
double circulating_supply = 32;
|
||||
double market_cap = 33;
|
||||
}
|
||||
33
yfinance/pricing_pb2.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: pricing.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import message as _message
|
||||
from google.protobuf import reflection as _reflection
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rpricing.proto\"\x9a\x05\n\x0bPricingData\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05price\x18\x02 \x01(\x02\x12\x0c\n\x04time\x18\x03 \x01(\x12\x12\x10\n\x08\x63urrency\x18\x04 \x01(\t\x12\x10\n\x08\x65xchange\x18\x05 \x01(\t\x12\x12\n\nquote_type\x18\x06 \x01(\x05\x12\x14\n\x0cmarket_hours\x18\x07 \x01(\x05\x12\x16\n\x0e\x63hange_percent\x18\x08 \x01(\x02\x12\x12\n\nday_volume\x18\t \x01(\x12\x12\x10\n\x08\x64\x61y_high\x18\n \x01(\x02\x12\x0f\n\x07\x64\x61y_low\x18\x0b \x01(\x02\x12\x0e\n\x06\x63hange\x18\x0c \x01(\x02\x12\x12\n\nshort_name\x18\r \x01(\t\x12\x13\n\x0b\x65xpire_date\x18\x0e \x01(\x12\x12\x12\n\nopen_price\x18\x0f \x01(\x02\x12\x16\n\x0eprevious_close\x18\x10 \x01(\x02\x12\x14\n\x0cstrike_price\x18\x11 \x01(\x02\x12\x19\n\x11underlying_symbol\x18\x12 \x01(\t\x12\x15\n\ropen_interest\x18\x13 \x01(\x12\x12\x14\n\x0coptions_type\x18\x14 \x01(\x12\x12\x13\n\x0bmini_option\x18\x15 \x01(\x12\x12\x11\n\tlast_size\x18\x16 \x01(\x12\x12\x0b\n\x03\x62id\x18\x17 \x01(\x02\x12\x10\n\x08\x62id_size\x18\x18 \x01(\x12\x12\x0b\n\x03\x61sk\x18\x19 \x01(\x02\x12\x10\n\x08\x61sk_size\x18\x1a \x01(\x12\x12\x12\n\nprice_hint\x18\x1b \x01(\x12\x12\x10\n\x08vol_24hr\x18\x1c \x01(\x12\x12\x1a\n\x12vol_all_currencies\x18\x1d \x01(\x12\x12\x15\n\rfrom_currency\x18\x1e \x01(\t\x12\x13\n\x0blast_market\x18\x1f \x01(\t\x12\x1a\n\x12\x63irculating_supply\x18 \x01(\x01\x12\x12\n\nmarket_cap\x18! \x01(\x01\x62\x06proto3')
|
||||
|
||||
|
||||
|
||||
_PRICINGDATA = DESCRIPTOR.message_types_by_name['PricingData']
|
||||
PricingData = _reflection.GeneratedProtocolMessageType('PricingData', (_message.Message,), {
|
||||
'DESCRIPTOR' : _PRICINGDATA,
|
||||
'__module__' : 'pricing_pb2'
|
||||
# @@protoc_insertion_point(class_scope:PricingData)
|
||||
})
|
||||
_sym_db.RegisterMessage(PricingData)
|
||||
|
||||
if not _descriptor._USE_C_DESCRIPTORS:
|
||||
DESCRIPTOR._options = None
|
||||
_PRICINGDATA._serialized_start=18
|
||||
_PRICINGDATA._serialized_end=684
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,19 +1,22 @@
|
||||
import curl_cffi
|
||||
import pandas as pd
|
||||
import requests
|
||||
import warnings
|
||||
|
||||
from yfinance import utils
|
||||
from yfinance.const import quote_summary_valid_modules, _SENTINEL_
|
||||
from yfinance.data import YfData
|
||||
from yfinance.const import quote_summary_valid_modules
|
||||
from yfinance.scrapers.quote import _QUOTE_SUMMARY_URL_
|
||||
from yfinance.exceptions import YFException
|
||||
|
||||
from yfinance.scrapers.quote import _QUOTE_SUMMARY_URL_
|
||||
|
||||
class Analysis:
|
||||
|
||||
def __init__(self, data: YfData, symbol: str, proxy=None):
|
||||
def __init__(self, data: YfData, symbol: str, proxy=_SENTINEL_):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
data._set_proxy(proxy)
|
||||
|
||||
self._data = data
|
||||
self._symbol = symbol
|
||||
self.proxy = proxy
|
||||
|
||||
# In quoteSummary the 'earningsTrend' module contains most of the data below.
|
||||
# The format of data is not optimal so each function will process it's part of the data.
|
||||
@@ -175,8 +178,8 @@ class Analysis:
|
||||
raise YFException("No valid modules provided, see available modules using `valid_modules`")
|
||||
params_dict = {"modules": modules, "corsDomain": "finance.yahoo.com", "formatted": "false", "symbol": self._symbol}
|
||||
try:
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_ + f"/{self._symbol}", user_agent_headers=self._data.user_agent_headers, params=params_dict, proxy=self.proxy)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_ + f"/{self._symbol}", params=params_dict)
|
||||
except curl_cffi.requests.exceptions.HTTPError as e:
|
||||
utils.get_yf_logger().error(str(e))
|
||||
return None
|
||||
return result
|
||||
|
||||
@@ -10,10 +10,13 @@ from yfinance.exceptions import YFException, YFNotImplementedError
|
||||
|
||||
class Fundamentals:
|
||||
|
||||
def __init__(self, data: YfData, symbol: str, proxy=None):
|
||||
def __init__(self, data: YfData, symbol: str, proxy=const._SENTINEL_):
|
||||
if proxy is not const._SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
data._set_proxy(proxy)
|
||||
|
||||
self._data = data
|
||||
self._symbol = symbol
|
||||
self.proxy = proxy
|
||||
|
||||
self._earnings = None
|
||||
self._financials = None
|
||||
@@ -48,40 +51,55 @@ class Financials:
|
||||
self._balance_sheet_time_series = {}
|
||||
self._cash_flow_time_series = {}
|
||||
|
||||
def get_income_time_series(self, freq="yearly", proxy=None) -> pd.DataFrame:
|
||||
def get_income_time_series(self, freq="yearly", proxy=const._SENTINEL_) -> pd.DataFrame:
|
||||
if proxy is not const._SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
res = self._income_time_series
|
||||
if freq not in res:
|
||||
res[freq] = self._fetch_time_series("income", freq, proxy)
|
||||
res[freq] = self._fetch_time_series("income", freq)
|
||||
return res[freq]
|
||||
|
||||
def get_balance_sheet_time_series(self, freq="yearly", proxy=None) -> pd.DataFrame:
|
||||
def get_balance_sheet_time_series(self, freq="yearly", proxy=const._SENTINEL_) -> pd.DataFrame:
|
||||
if proxy is not const._SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
res = self._balance_sheet_time_series
|
||||
if freq not in res:
|
||||
res[freq] = self._fetch_time_series("balance-sheet", freq, proxy)
|
||||
res[freq] = self._fetch_time_series("balance-sheet", freq)
|
||||
return res[freq]
|
||||
|
||||
def get_cash_flow_time_series(self, freq="yearly", proxy=None) -> pd.DataFrame:
|
||||
def get_cash_flow_time_series(self, freq="yearly", proxy=const._SENTINEL_) -> pd.DataFrame:
|
||||
if proxy is not const._SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
res = self._cash_flow_time_series
|
||||
if freq not in res:
|
||||
res[freq] = self._fetch_time_series("cash-flow", freq, proxy)
|
||||
res[freq] = self._fetch_time_series("cash-flow", freq)
|
||||
return res[freq]
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _fetch_time_series(self, name, timescale, proxy=None):
|
||||
def _fetch_time_series(self, name, timescale):
|
||||
# Fetching time series preferred over scraping 'QuoteSummaryStore',
|
||||
# because it matches what Yahoo shows. But for some tickers returns nothing,
|
||||
# despite 'QuoteSummaryStore' containing valid data.
|
||||
|
||||
allowed_names = ["income", "balance-sheet", "cash-flow"]
|
||||
allowed_timescales = ["yearly", "quarterly"]
|
||||
allowed_timescales = ["yearly", "quarterly", "trailing"]
|
||||
|
||||
if name not in allowed_names:
|
||||
raise ValueError(f"Illegal argument: name must be one of: {allowed_names}")
|
||||
if timescale not in allowed_timescales:
|
||||
raise ValueError(f"Illegal argument: timescale must be one of: {allowed_timescales}")
|
||||
if timescale == "trailing" and name not in ('income', 'cash-flow'):
|
||||
raise ValueError("Illegal argument: frequency 'trailing'" +
|
||||
" only available for cash-flow or income data.")
|
||||
|
||||
try:
|
||||
statement = self._create_financials_table(name, timescale, proxy)
|
||||
statement = self._create_financials_table(name, timescale)
|
||||
|
||||
if statement is not None:
|
||||
return statement
|
||||
@@ -89,7 +107,7 @@ class Financials:
|
||||
utils.get_yf_logger().error(f"{self._symbol}: Failed to create {name} financials table for reason: {e}")
|
||||
return pd.DataFrame()
|
||||
|
||||
def _create_financials_table(self, name, timescale, proxy):
|
||||
def _create_financials_table(self, name, timescale):
|
||||
if name == "income":
|
||||
# Yahoo stores the 'income' table internally under 'financials' key
|
||||
name = "financials"
|
||||
@@ -97,12 +115,12 @@ class Financials:
|
||||
keys = const.fundamentals_keys[name]
|
||||
|
||||
try:
|
||||
return self.get_financials_time_series(timescale, keys, proxy)
|
||||
return self._get_financials_time_series(timescale, keys)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def get_financials_time_series(self, timescale, keys: list, proxy=None) -> pd.DataFrame:
|
||||
timescale_translation = {"yearly": "annual", "quarterly": "quarterly"}
|
||||
def _get_financials_time_series(self, timescale, keys: list) -> pd.DataFrame:
|
||||
timescale_translation = {"yearly": "annual", "quarterly": "quarterly", "trailing": "trailing"}
|
||||
timescale = timescale_translation[timescale]
|
||||
|
||||
# Step 2: construct url:
|
||||
@@ -114,7 +132,7 @@ class Financials:
|
||||
url += f"&period1={int(start_dt.timestamp())}&period2={int(end.timestamp())}"
|
||||
|
||||
# Step 3: fetch and reshape data
|
||||
json_str = self._data.cache_get(url=url, proxy=proxy).text
|
||||
json_str = self._data.cache_get(url=url).text
|
||||
json_data = json.loads(json_str)
|
||||
data_raw = json_data["timeseries"]["result"]
|
||||
# data_raw = [v for v in data_raw if len(v) > 1] # Discard keys with no data
|
||||
@@ -141,8 +159,16 @@ class Financials:
|
||||
|
||||
df.index = df.index.str.replace("^" + timescale, "", regex=True)
|
||||
|
||||
# Ensure float type, not object
|
||||
for d in df.columns:
|
||||
df[d] = df[d].astype('float')
|
||||
|
||||
# Reorder table to match order on Yahoo website
|
||||
df = df.reindex([k for k in keys if k in df.index])
|
||||
df = df[sorted(df.columns, reverse=True)]
|
||||
|
||||
# Trailing 12 months return only the first column.
|
||||
if (timescale == "trailing"):
|
||||
df = df.iloc[:, [0]]
|
||||
|
||||
return df
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import pandas as pd
|
||||
|
||||
from yfinance.data import YfData
|
||||
from yfinance.const import _BASE_URL_
|
||||
from yfinance.exceptions import YFDataException
|
||||
from yfinance import utils
|
||||
|
||||
from typing import Dict, Optional
|
||||
import warnings
|
||||
|
||||
from yfinance import utils
|
||||
from yfinance.const import _BASE_URL_, _SENTINEL_
|
||||
from yfinance.data import YfData
|
||||
from yfinance.exceptions import YFDataException
|
||||
|
||||
_QUOTE_SUMMARY_URL_ = f"{_BASE_URL_}/v10/finance/quoteSummary/"
|
||||
|
||||
@@ -17,16 +17,17 @@ class FundsData:
|
||||
Notes:
|
||||
- fundPerformance module is not implemented as better data is queryable using history
|
||||
"""
|
||||
def __init__(self, data: YfData, symbol: str, proxy=None):
|
||||
def __init__(self, data: YfData, symbol: str, proxy=_SENTINEL_):
|
||||
"""
|
||||
Args:
|
||||
data (YfData): The YfData object for fetching data.
|
||||
symbol (str): The symbol of the fund.
|
||||
proxy (optional): Proxy settings for fetching data.
|
||||
"""
|
||||
self._data = data
|
||||
self._symbol = symbol
|
||||
self.proxy = proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
# quoteType
|
||||
self._quote_type = None
|
||||
@@ -165,26 +166,23 @@ class FundsData:
|
||||
self._fetch_and_parse()
|
||||
return self._sector_weightings
|
||||
|
||||
def _fetch(self, proxy):
|
||||
def _fetch(self):
|
||||
"""
|
||||
Fetches the raw JSON data from the API.
|
||||
|
||||
Args:
|
||||
proxy: Proxy settings for fetching data.
|
||||
|
||||
Returns:
|
||||
dict: The raw JSON data.
|
||||
"""
|
||||
modules = ','.join(["quoteType", "summaryProfile", "topHoldings", "fundProfile"])
|
||||
params_dict = {"modules": modules, "corsDomain": "finance.yahoo.com", "symbol": self._symbol, "formatted": "false"}
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_+self._symbol, user_agent_headers=self._data.user_agent_headers, params=params_dict, proxy=proxy)
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_+self._symbol, params=params_dict)
|
||||
return result
|
||||
|
||||
def _fetch_and_parse(self) -> None:
|
||||
"""
|
||||
Fetches and parses the data from the API.
|
||||
"""
|
||||
result = self._fetch(self.proxy)
|
||||
result = self._fetch()
|
||||
try:
|
||||
data = result["quoteSummary"]["result"][0]
|
||||
# check quote type
|
||||
@@ -334,4 +332,4 @@ class FundsData:
|
||||
self._parse_raw_values(_fund_operations_cat.get("annualHoldingsTurnover", pd.NA)),
|
||||
self._parse_raw_values(_fund_operations_cat.get("totalNetAssets", pd.NA))
|
||||
]
|
||||
}).set_index("Attributes")
|
||||
}).set_index("Attributes")
|
||||
|
||||
@@ -1,25 +1,29 @@
|
||||
from curl_cffi import requests
|
||||
from math import isclose
|
||||
import bisect
|
||||
import datetime as _datetime
|
||||
import dateutil as _dateutil
|
||||
import logging
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
from math import isclose
|
||||
import time as _time
|
||||
import bisect
|
||||
import warnings
|
||||
|
||||
from yfinance import shared, utils
|
||||
from yfinance.const import _BASE_URL_, _PRICE_COLNAMES_
|
||||
from yfinance.const import _BASE_URL_, _PRICE_COLNAMES_, _SENTINEL_
|
||||
from yfinance.exceptions import YFInvalidPeriodError, YFPricesMissingError, YFTzMissingError, YFRateLimitError
|
||||
|
||||
class PriceHistory:
|
||||
def __init__(self, data, ticker, tz, session=None, proxy=None):
|
||||
def __init__(self, data, ticker, tz, session=None, proxy=_SENTINEL_):
|
||||
self._data = data
|
||||
self.ticker = ticker.upper()
|
||||
self.tz = tz
|
||||
self.proxy = proxy
|
||||
self.session = session
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=5)
|
||||
self._data._set_proxy(proxy)
|
||||
self.session = session or requests.Session(impersonate="chrome")
|
||||
|
||||
self._history = None
|
||||
self._history_cache = {}
|
||||
self._history_metadata = None
|
||||
self._history_metadata_formatted = False
|
||||
|
||||
@@ -27,54 +31,57 @@ class PriceHistory:
|
||||
self._reconstruct_start_interval = None
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def history(self, period="1mo", interval="1d",
|
||||
def history(self, period=None, interval="1d",
|
||||
start=None, end=None, prepost=False, actions=True,
|
||||
auto_adjust=True, back_adjust=False, repair=False, keepna=False,
|
||||
proxy=None, rounding=False, timeout=10,
|
||||
proxy=_SENTINEL_, rounding=False, timeout=10,
|
||||
raise_errors=False) -> pd.DataFrame:
|
||||
"""
|
||||
:Parameters:
|
||||
period : str
|
||||
Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
|
||||
Either Use period parameter or use start and end
|
||||
| Valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
|
||||
| Default: 1mo
|
||||
| Can combine with start/end e.g. end = start + period
|
||||
interval : str
|
||||
Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
|
||||
Intraday data cannot extend last 60 days
|
||||
start: str
|
||||
Download start date string (YYYY-MM-DD) or _datetime, inclusive.
|
||||
Default is 99 years ago
|
||||
E.g. for start="2020-01-01", the first data point will be on "2020-01-01"
|
||||
end: str
|
||||
Download end date string (YYYY-MM-DD) or _datetime, exclusive.
|
||||
Default is now
|
||||
E.g. for end="2023-01-01", the last data point will be on "2022-12-31"
|
||||
| Valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
|
||||
| Intraday data cannot extend last 60 days
|
||||
start : str
|
||||
| Download start date string (YYYY-MM-DD) or _datetime, inclusive.
|
||||
| Default: 99 years ago
|
||||
| E.g. for start="2020-01-01", first data point = "2020-01-01"
|
||||
end : str
|
||||
| Download end date string (YYYY-MM-DD) or _datetime, exclusive.
|
||||
| Default: now
|
||||
| E.g. for end="2023-01-01", last data point = "2022-12-31"
|
||||
prepost : bool
|
||||
Include Pre and Post market data in results?
|
||||
Default is False
|
||||
auto_adjust: bool
|
||||
Adjust all OHLC automatically? Default is True
|
||||
back_adjust: bool
|
||||
Back-adjusted data to mimic true historical prices
|
||||
repair: bool
|
||||
Detect currency unit 100x mixups and attempt repair.
|
||||
Default is False
|
||||
keepna: bool
|
||||
Keep NaN rows returned by Yahoo?
|
||||
Default is False
|
||||
proxy: str
|
||||
Optional. Proxy server URL scheme. Default is None
|
||||
rounding: bool
|
||||
Round values to 2 decimal places?
|
||||
Optional. Default is False = precision suggested by Yahoo!
|
||||
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)
|
||||
Default is 10 seconds.
|
||||
raise_errors: bool
|
||||
| Include Pre and Post market data in results?
|
||||
| Default: False
|
||||
auto_adjust : bool
|
||||
| Adjust all OHLC automatically?
|
||||
| Default: True
|
||||
back_adjust : bool
|
||||
| Back-adjusted data to mimic true historical prices
|
||||
repair : bool
|
||||
| Fixes price errors in Yahoo data: 100x, missing, bad dividend adjust.
|
||||
| Default: False
|
||||
| Full details at: :doc:`../advanced/price_repair`.
|
||||
keepna : bool
|
||||
| Keep NaN rows returned by Yahoo?
|
||||
| Default: False
|
||||
rounding : bool
|
||||
| Optional: Round values to 2 decimal places?
|
||||
| Default: False = use precision suggested by Yahoo!
|
||||
timeout : None or float
|
||||
| Optional: timeout fetches after N seconds
|
||||
| Default: 10 seconds
|
||||
raise_errors : bool
|
||||
If True, then raise errors as Exceptions instead of logging.
|
||||
"""
|
||||
logger = utils.get_yf_logger()
|
||||
proxy = proxy or self.proxy
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=5)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
interval_user = interval
|
||||
period_user = period
|
||||
@@ -108,7 +115,7 @@ class PriceHistory:
|
||||
|
||||
start_user = start
|
||||
end_user = end
|
||||
if start or period is None or period.lower() == "max":
|
||||
if start or end or (period and period.lower() == "max"):
|
||||
# Check can get TZ. Fail => probably delisted
|
||||
tz = self.tz
|
||||
if tz is None:
|
||||
@@ -123,21 +130,49 @@ class PriceHistory:
|
||||
logger.error(err_msg)
|
||||
return utils.empty_df()
|
||||
|
||||
if end is None:
|
||||
end = int(_time.time())
|
||||
else:
|
||||
end = utils._parse_user_dt(end, tz)
|
||||
if start is None:
|
||||
if interval == "1m":
|
||||
start = end - 604800 # 7 days
|
||||
elif interval in ("5m", "15m", "30m", "90m"):
|
||||
start = end - 5184000 # 60 days
|
||||
elif interval in ("1h", '60m'):
|
||||
start = end - 63072000 # 730 days
|
||||
else:
|
||||
start = end - 3122064000 # 99 years
|
||||
else:
|
||||
start = utils._parse_user_dt(start, tz)
|
||||
if start:
|
||||
start_dt = utils._parse_user_dt(start, tz)
|
||||
start = int(start_dt.timestamp())
|
||||
if end:
|
||||
end_dt = utils._parse_user_dt(end, tz)
|
||||
end = int(end_dt.timestamp())
|
||||
|
||||
if period is None:
|
||||
if not (start or end):
|
||||
period = '1mo' # default
|
||||
elif not start:
|
||||
start_dt = end_dt - utils._interval_to_timedelta('1mo')
|
||||
start = int(start_dt.timestamp())
|
||||
elif not end:
|
||||
end_dt = pd.Timestamp.utcnow().tz_convert(tz)
|
||||
end = int(end_dt.timestamp())
|
||||
else:
|
||||
if period.lower() == "max":
|
||||
if end is None:
|
||||
end = int(_time.time())
|
||||
if start is None:
|
||||
if interval == "1m":
|
||||
start = end - 691200 # 8 days
|
||||
elif interval in ("2m", "5m", "15m", "30m", "90m"):
|
||||
start = end - 5184000 # 60 days
|
||||
elif interval in ("1h", "60m"):
|
||||
start = end - 63072000 # 730 days
|
||||
else:
|
||||
start = end - 3122064000 # 99 years
|
||||
start += 5 # allow for processing time
|
||||
elif start and end:
|
||||
raise ValueError("Setting period, start and end is nonsense. Set maximum 2 of them.")
|
||||
elif start or end:
|
||||
period_td = utils._interval_to_timedelta(period)
|
||||
if end is None:
|
||||
end_dt = start_dt + period_td
|
||||
end = int(end_dt.timestamp())
|
||||
if start is None:
|
||||
start_dt = end_dt - period_td
|
||||
start = int(start_dt.timestamp())
|
||||
period = None
|
||||
|
||||
if start or end:
|
||||
params = {"period1": start, "period2": end}
|
||||
else:
|
||||
period = period.lower()
|
||||
@@ -175,7 +210,6 @@ class PriceHistory:
|
||||
data = get_fn(
|
||||
url=url,
|
||||
params=params,
|
||||
proxy=proxy,
|
||||
timeout=timeout
|
||||
)
|
||||
if "Will be right back" in data.text or data is None:
|
||||
@@ -249,9 +283,16 @@ class PriceHistory:
|
||||
self._reconstruct_start_interval = None
|
||||
return utils.empty_df()
|
||||
|
||||
# Select useful info from metadata
|
||||
quote_type = self._history_metadata["instrumentType"]
|
||||
expect_capital_gains = quote_type in ('MUTUALFUND', 'ETF')
|
||||
tz_exchange = self._history_metadata["exchangeTimezoneName"]
|
||||
currency = self._history_metadata["currency"]
|
||||
|
||||
# Process custom periods
|
||||
if period and period not in self._history_metadata.get("validRanges", []):
|
||||
end = int(_time.time())
|
||||
end_dt = pd.Timestamp(end, unit='s').tz_localize("UTC")
|
||||
start = _datetime.date.fromtimestamp(end)
|
||||
start -= utils._interval_to_timedelta(period)
|
||||
start -= _datetime.timedelta(days=4)
|
||||
@@ -260,9 +301,8 @@ class PriceHistory:
|
||||
quotes = utils.parse_quotes(data["chart"]["result"][0])
|
||||
# Yahoo bug fix - it often appends latest price even if after end date
|
||||
if end and not quotes.empty:
|
||||
endDt = pd.to_datetime(end, unit='s')
|
||||
if quotes.index[quotes.shape[0] - 1] >= endDt:
|
||||
quotes = quotes.iloc[0:quotes.shape[0] - 1]
|
||||
if quotes.index[-1] >= end_dt.tz_convert('UTC').tz_localize(None):
|
||||
quotes = quotes.drop(quotes.index[-1])
|
||||
if quotes.empty:
|
||||
msg = f'{self.ticker}: yfinance received OHLC data: EMPTY'
|
||||
elif len(quotes) == 1:
|
||||
@@ -289,12 +329,6 @@ class PriceHistory:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Select useful info from metadata
|
||||
quote_type = self._history_metadata["instrumentType"]
|
||||
expect_capital_gains = quote_type in ('MUTUALFUND', 'ETF')
|
||||
tz_exchange = self._history_metadata["exchangeTimezoneName"]
|
||||
currency = self._history_metadata["currency"]
|
||||
|
||||
# Note: ordering is important. If you change order, run the tests!
|
||||
quotes = utils.set_df_tz(quotes, params["interval"], tz_exchange)
|
||||
quotes = utils.fix_Yahoo_dst_issue(quotes, params["interval"])
|
||||
@@ -323,25 +357,44 @@ class PriceHistory:
|
||||
splits = utils.set_df_tz(splits, interval, tz_exchange)
|
||||
if dividends is not None:
|
||||
dividends = utils.set_df_tz(dividends, interval, tz_exchange)
|
||||
if 'currency' in dividends.columns:
|
||||
# Rare, only seen with Vietnam market
|
||||
price_currency = self._history_metadata['currency']
|
||||
if price_currency is None:
|
||||
price_currency = ''
|
||||
f_currency_mismatch = dividends['currency'] != price_currency
|
||||
if f_currency_mismatch.any():
|
||||
if not repair or price_currency == '':
|
||||
# Append currencies to values, let user decide action.
|
||||
dividends['Dividends'] = dividends['Dividends'].astype(str) + ' ' + dividends['currency']
|
||||
else:
|
||||
# Attempt repair = currency conversion
|
||||
dividends = self._dividends_convert_fx(dividends, price_currency, repair)
|
||||
if (dividends['currency'] != price_currency).any():
|
||||
# FX conversion failed
|
||||
dividends['Dividends'] = dividends['Dividends'].astype(str) + ' ' + dividends['currency']
|
||||
dividends = dividends.drop('currency', axis=1)
|
||||
|
||||
if capital_gains is not None:
|
||||
capital_gains = utils.set_df_tz(capital_gains, interval, tz_exchange)
|
||||
if start is not None:
|
||||
if not quotes.empty:
|
||||
startDt = quotes.index[0].floor('D')
|
||||
start_d = quotes.index[0].floor('D')
|
||||
if dividends is not None:
|
||||
dividends = dividends.loc[startDt:]
|
||||
dividends = dividends.loc[start_d:]
|
||||
if capital_gains is not None:
|
||||
capital_gains = capital_gains.loc[startDt:]
|
||||
capital_gains = capital_gains.loc[start_d:]
|
||||
if splits is not None:
|
||||
splits = splits.loc[startDt:]
|
||||
splits = splits.loc[start_d:]
|
||||
if end is not None:
|
||||
endDt = pd.Timestamp(end, unit='s').tz_localize(tz)
|
||||
# -1 because date-slice end is inclusive
|
||||
end_dt_sub1 = end_dt - pd.Timedelta(1)
|
||||
if dividends is not None:
|
||||
dividends = dividends[dividends.index < endDt]
|
||||
dividends = dividends[:end_dt_sub1]
|
||||
if capital_gains is not None:
|
||||
capital_gains = capital_gains[capital_gains.index < endDt]
|
||||
capital_gains = capital_gains[:end_dt_sub1]
|
||||
if splits is not None:
|
||||
splits = splits[splits.index < endDt]
|
||||
splits = splits[:end_dt_sub1]
|
||||
|
||||
# Prepare for combine
|
||||
intraday = params["interval"][-1] in ("m", 'h')
|
||||
@@ -383,7 +436,9 @@ class PriceHistory:
|
||||
msg = f'{self.ticker}: OHLC after combining events: {df.index[0]} -> {df.index[-1]}'
|
||||
logger.debug(msg)
|
||||
|
||||
df = utils.fix_Yahoo_returning_live_separate(df, params["interval"], tz_exchange, repair=repair, currency=currency)
|
||||
df, last_trade = utils.fix_Yahoo_returning_live_separate(df, params["interval"], tz_exchange, prepost, repair=repair, currency=currency)
|
||||
if last_trade is not None:
|
||||
self._history_metadata['lastTrade'] = {'Price':last_trade['Close'], "Time":last_trade.name}
|
||||
|
||||
df = df[~df.index.duplicated(keep='first')] # must do before repair
|
||||
|
||||
@@ -397,14 +452,16 @@ class PriceHistory:
|
||||
# First make currency consistent. On some exchanges, dividends often in different currency
|
||||
# to prices, e.g. £ vs pence.
|
||||
df, currency = self._standardise_currency(df, currency)
|
||||
self._history_metadata['currency'] = currency
|
||||
|
||||
df = self._fix_bad_div_adjust(df, interval, currency)
|
||||
|
||||
# Need the latest/last row to be repaired before 100x/split repair:
|
||||
df_last = self._fix_zeroes(df.iloc[-1:], interval, tz_exchange, prepost)
|
||||
if 'Repaired?' not in df.columns:
|
||||
df['Repaired?'] = False
|
||||
df = pd.concat([df.drop(df.index[-1]), df_last])
|
||||
if not df.empty:
|
||||
df_last = self._fix_zeroes(df.iloc[-1:], interval, tz_exchange, prepost)
|
||||
if 'Repaired?' not in df.columns:
|
||||
df['Repaired?'] = False
|
||||
df = pd.concat([df.drop(df.index[-1]), df_last])
|
||||
|
||||
df = self._fix_unit_mixups(df, interval, tz_exchange, prepost)
|
||||
df = self._fix_bad_stock_splits(df, interval, tz_exchange)
|
||||
@@ -439,8 +496,6 @@ class PriceHistory:
|
||||
else:
|
||||
df.index.name = "Date"
|
||||
|
||||
self._history = df.copy()
|
||||
|
||||
# missing rows cleanup
|
||||
if not actions:
|
||||
df = df.drop(columns=["Dividends", "Stock Splits", "Capital Gains"], errors='ignore')
|
||||
@@ -465,10 +520,23 @@ class PriceHistory:
|
||||
self._reconstruct_start_interval = None
|
||||
return df
|
||||
|
||||
def get_history_metadata(self, proxy=None) -> dict:
|
||||
if self._history_metadata is None:
|
||||
# Request intraday data, because then Yahoo returns exchange schedule.
|
||||
self.history(period="5d", interval="1h", prepost=True, proxy=proxy)
|
||||
def _get_history_cache(self, period="max", interval="1d") -> pd.DataFrame:
|
||||
cache_key = (interval, period)
|
||||
if cache_key in self._history_cache:
|
||||
return self._history_cache[cache_key]
|
||||
|
||||
df = self.history(period=period, interval=interval, prepost=True)
|
||||
self._history_cache[cache_key] = df
|
||||
return df
|
||||
|
||||
def get_history_metadata(self, proxy=_SENTINEL_) -> dict:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=3)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
if self._history_metadata is None or 'tradingPeriods' not in self._history_metadata:
|
||||
# Request intraday data, because then Yahoo returns exchange schedule (tradingPeriods).
|
||||
self._get_history_cache(period="5d", interval="1h")
|
||||
|
||||
if self._history_metadata_formatted is False:
|
||||
self._history_metadata = utils.format_history_metadata(self._history_metadata)
|
||||
@@ -476,38 +544,56 @@ class PriceHistory:
|
||||
|
||||
return self._history_metadata
|
||||
|
||||
def get_dividends(self, proxy=None) -> pd.Series:
|
||||
if self._history is None:
|
||||
self.history(period="max", proxy=proxy)
|
||||
if self._history is not None and "Dividends" in self._history:
|
||||
dividends = self._history["Dividends"]
|
||||
def get_dividends(self, period="max", proxy=_SENTINEL_) -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=3)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
df = self._get_history_cache(period=period)
|
||||
if "Dividends" in df.columns:
|
||||
dividends = df["Dividends"]
|
||||
return dividends[dividends != 0]
|
||||
return pd.Series()
|
||||
|
||||
def get_capital_gains(self, proxy=None) -> pd.Series:
|
||||
if self._history is None:
|
||||
self.history(period="max", proxy=proxy)
|
||||
if self._history is not None and "Capital Gains" in self._history:
|
||||
capital_gains = self._history["Capital Gains"]
|
||||
def get_capital_gains(self, period="max", proxy=_SENTINEL_) -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=3)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
df = self._get_history_cache(period=period)
|
||||
if "Capital Gains" in df.columns:
|
||||
capital_gains = df["Capital Gains"]
|
||||
return capital_gains[capital_gains != 0]
|
||||
return pd.Series()
|
||||
|
||||
def get_splits(self, proxy=None) -> pd.Series:
|
||||
if self._history is None:
|
||||
self.history(period="max", proxy=proxy)
|
||||
if self._history is not None and "Stock Splits" in self._history:
|
||||
splits = self._history["Stock Splits"]
|
||||
def get_splits(self, period="max", proxy=_SENTINEL_) -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=3)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
df = self._get_history_cache(period=period)
|
||||
if "Stock Splits" in df.columns:
|
||||
splits = df["Stock Splits"]
|
||||
return splits[splits != 0]
|
||||
return pd.Series()
|
||||
|
||||
def get_actions(self, proxy=None) -> pd.Series:
|
||||
if self._history is None:
|
||||
self.history(period="max", proxy=proxy)
|
||||
if self._history is not None and "Dividends" in self._history and "Stock Splits" in self._history:
|
||||
action_columns = ["Dividends", "Stock Splits"]
|
||||
if "Capital Gains" in self._history:
|
||||
action_columns.append("Capital Gains")
|
||||
actions = self._history[action_columns]
|
||||
def get_actions(self, period="max", proxy=_SENTINEL_) -> pd.Series:
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=3)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
df = self._get_history_cache(period=period)
|
||||
|
||||
action_columns = []
|
||||
if "Dividends" in df.columns:
|
||||
action_columns.append("Dividends")
|
||||
if "Stock Splits" in df.columns:
|
||||
action_columns.append("Stock Splits")
|
||||
if "Capital Gains" in df.columns:
|
||||
action_columns.append("Capital Gains")
|
||||
|
||||
if action_columns:
|
||||
actions = df[action_columns]
|
||||
return actions[actions != 0].dropna(how='all').fillna(0)
|
||||
return pd.Series()
|
||||
|
||||
@@ -981,6 +1067,45 @@ class PriceHistory:
|
||||
|
||||
return df, currency2
|
||||
|
||||
def _dividends_convert_fx(self, dividends, fx, repair=False):
|
||||
bad_div_currencies = [c for c in dividends['currency'].unique() if c != fx]
|
||||
major_currencies = ['USD', 'JPY', 'EUR', 'CNY', 'GBP', 'CAD']
|
||||
for c in bad_div_currencies:
|
||||
fx2_tkr = None
|
||||
if c == 'USD':
|
||||
# Simple convert from USD to target FX
|
||||
fx_tkr = f'{fx}=X'
|
||||
reverse = False
|
||||
elif fx == 'USD':
|
||||
# Use same USD FX but reversed
|
||||
fx_tkr = f'{fx}=X'
|
||||
reverse = True
|
||||
elif c in major_currencies and fx in major_currencies:
|
||||
# Simple convert
|
||||
fx_tkr = f'{c}{fx}=X'
|
||||
reverse = False
|
||||
else:
|
||||
# No guarantee that Yahoo has direct FX conversion, so
|
||||
# convert via USD
|
||||
# - step 1: -> USD
|
||||
fx_tkr = f'{c}=X'
|
||||
reverse = True
|
||||
# - step 2: USD -> FX
|
||||
fx2_tkr = f'{fx}=X'
|
||||
|
||||
fx_dat = PriceHistory(self._data, fx_tkr, self.session)
|
||||
fx_rate = fx_dat.history(period='1mo', repair=repair)['Close'].iloc[-1]
|
||||
if reverse:
|
||||
fx_rate = 1/fx_rate
|
||||
dividends.loc[dividends['currency']==c, 'Dividends'] *= fx_rate
|
||||
if fx2_tkr is not None:
|
||||
fx2_dat = PriceHistory(self._data, fx2_tkr, self.session)
|
||||
fx2_rate = fx2_dat.history(period='1mo', repair=repair)['Close'].iloc[-1]
|
||||
dividends.loc[dividends['currency']==c, 'Dividends'] *= fx2_rate
|
||||
|
||||
dividends['currency'] = fx
|
||||
return dividends
|
||||
|
||||
@utils.log_indent_decorator
|
||||
def _fix_unit_mixups(self, df, interval, tz_exchange, prepost):
|
||||
if df.empty:
|
||||
@@ -1304,7 +1429,7 @@ class PriceHistory:
|
||||
|
||||
if df is None or df.empty:
|
||||
return df
|
||||
if interval != '1d':
|
||||
if interval in ['1wk', '1mo', '3mo', '1y']:
|
||||
return df
|
||||
|
||||
logger = utils.get_yf_logger()
|
||||
@@ -1614,9 +1739,9 @@ class PriceHistory:
|
||||
checks += ['adj_missing', 'adj_exceeds_div', 'div_exceeds_adj']
|
||||
|
||||
div_status_df['phantom'] = False
|
||||
phantom_proximity_threshold = _datetime.timedelta(days=7)
|
||||
phantom_proximity_threshold = _datetime.timedelta(days=17)
|
||||
f = div_status_df[['div_too_big', 'div_exceeds_adj']].any(axis=1)
|
||||
if f.any():
|
||||
if f.any() and len(div_status_df) > 1:
|
||||
# One/some of these may be phantom dividends. Clue is if another correct dividend is very close
|
||||
indices = np.where(f)[0]
|
||||
dts_to_check = div_status_df.index[f]
|
||||
@@ -1625,37 +1750,24 @@ class PriceHistory:
|
||||
div_dt = div.name
|
||||
phantom_dt = None
|
||||
if i > 0:
|
||||
prev_div = div_status_df.iloc[i-1]
|
||||
ratio1 = (div['div']/currency_divide) / prev_div['div']
|
||||
ratio2 = div['div'] / prev_div['div']
|
||||
divergence = min(abs(ratio1-1.0), abs(ratio2-1.0))
|
||||
if abs(div_dt-prev_div.name) <= phantom_proximity_threshold and not prev_div['phantom'] and divergence < 0.01:
|
||||
if prev_div.name in dts_to_check:
|
||||
# Both this and previous are anomalous, so mark smallest drop as phantom
|
||||
drop = div['drop']
|
||||
drop_prev = prev_div['drop']
|
||||
if drop > 1.5*drop_prev:
|
||||
phantom_dt = prev_div.name
|
||||
else:
|
||||
phantom_dt = div_dt
|
||||
else:
|
||||
phantom_dt = div_dt
|
||||
elif i < len(div_status_df)-1:
|
||||
next_div = div_status_df.iloc[i+1]
|
||||
ratio1 = (div['div']/currency_divide) / next_div['div']
|
||||
ratio2 = div['div'] / next_div['div']
|
||||
divergence = min(abs(ratio1-1.0), abs(ratio2-1.0))
|
||||
if abs(div_dt-next_div.name) <= phantom_proximity_threshold and divergence < 0.01:
|
||||
if next_div.name in dts_to_check:
|
||||
# Both this and previous are anomalous, so mark smallest drop as phantom
|
||||
drop = div['drop']
|
||||
drop_next = next_div['drop']
|
||||
if drop > 1.5*drop_next:
|
||||
phantom_dt = next_div.name
|
||||
else:
|
||||
phantom_dt = div_dt
|
||||
other_div = div_status_df.iloc[i-1]
|
||||
else:
|
||||
other_div = div_status_df.iloc[i+1]
|
||||
ratio1 = (div['div']/currency_divide) / other_div['div']
|
||||
ratio2 = div['div'] / other_div['div']
|
||||
divergence = min(abs(ratio1-1.0), abs(ratio2-1.0))
|
||||
if abs(div_dt-other_div.name) <= phantom_proximity_threshold and not other_div['phantom'] and divergence < 0.01:
|
||||
if other_div.name in dts_to_check:
|
||||
# Both this and previous are anomalous, so mark smallest drop as phantom
|
||||
drop = div['drop']
|
||||
drop_next = other_div['drop']
|
||||
if drop > 1.5*drop_next:
|
||||
phantom_dt = other_div.name
|
||||
else:
|
||||
phantom_dt = div_dt
|
||||
else:
|
||||
phantom_dt = div_dt
|
||||
|
||||
if phantom_dt:
|
||||
div_status_df.loc[phantom_dt, 'phantom'] = True
|
||||
for c in checks:
|
||||
@@ -1754,7 +1866,7 @@ class PriceHistory:
|
||||
lookahead_idx = bisect.bisect_left(df2.index, lookahead_date)
|
||||
lookahead_idx = min(lookahead_idx, len(df2)-1)
|
||||
# In rare cases, the price dropped 1 day before dividend (DVD.OL @ 2024-05-15)
|
||||
lookback_idx = div_idx-2 if div_idx > 1 else div_idx-1
|
||||
lookback_idx = max(0, div_idx-14)
|
||||
# Check for bad stock splits in the lookahead period -
|
||||
# if present, reduce lookahead to before.
|
||||
future_changes = df2['Close'].iloc[div_idx:lookahead_idx+1].pct_change()
|
||||
@@ -1776,8 +1888,6 @@ class PriceHistory:
|
||||
adjDeltas = x['Adj Low'].iloc[1:].to_numpy() - x['Adj Close'].iloc[:-1].to_numpy()
|
||||
adjDeltas = np.append([0.0], adjDeltas)
|
||||
x['adjDelta'] = adjDeltas
|
||||
for i in np.where(x['Dividends']>0)[0]:
|
||||
x.loc[x.index[i], 'adjDelta'] += x['Dividends'].iloc[i]*x['Adj'].iloc[i]
|
||||
deltas = x[['delta', 'adjDelta']]
|
||||
if div_pct > 0.05 and div_pct < 1.0:
|
||||
adjDiv = div * x['Adj'].iloc[0]
|
||||
@@ -1912,7 +2022,7 @@ class PriceHistory:
|
||||
pct_fail = n_fail / n
|
||||
if c == 'div_too_big':
|
||||
true_threshold = 1.0
|
||||
fals_threshold = 0.2
|
||||
fals_threshold = 0.25
|
||||
|
||||
if 'div_date_wrong' in cluster.columns and (cluster[c] == cluster['div_date_wrong']).all():
|
||||
continue
|
||||
@@ -1991,10 +2101,42 @@ class PriceHistory:
|
||||
if c == 'div_date_wrong':
|
||||
# Fine, these should be rare
|
||||
continue
|
||||
if c == 'div_pre_split':
|
||||
if c in ['div_pre_split', 'div_too_big_and_pre_split']:
|
||||
# Fine, these should be rare
|
||||
continue
|
||||
|
||||
if 'div_too_big' in checks and 'div_exceeds_adj' in checks:
|
||||
c = "adj_too_small"
|
||||
div_status_df[c] = False
|
||||
for i in range(len(div_status_df)):
|
||||
dt = div_status_df.index[i]
|
||||
row = div_status_df.iloc[i]
|
||||
if row['div_too_big'] and row['div_exceeds_adj']:
|
||||
# Check if div_too_big AND adj-too-small-for-prices
|
||||
div_yield = row['div']
|
||||
pct = row['%']
|
||||
close = div_yield/pct
|
||||
adj_present = row['present adj']
|
||||
implied_div_yield = (1-adj_present)*close
|
||||
ratio = div_yield/implied_div_yield
|
||||
also_correct_adj = abs(ratio-(currency_divide*currency_divide)) < currency_divide
|
||||
if also_correct_adj:
|
||||
div_status_df.loc[dt, c] = True
|
||||
if not div_status_df[c].any():
|
||||
div_status_df = div_status_df.drop(c, axis=1)
|
||||
else:
|
||||
checks.append(c)
|
||||
|
||||
if 'div_too_big_and_pre_split' in div_status_df.columns:
|
||||
for c in ['div_too_big', 'div_pre_split']:
|
||||
if c in div_status_df:
|
||||
div_status_df[c] = div_status_df[c] | div_status_df['div_too_big_and_pre_split']
|
||||
else:
|
||||
div_status_df[c] = div_status_df['div_too_big_and_pre_split']
|
||||
checks.append(c)
|
||||
div_status_df = div_status_df.drop('div_too_big_and_pre_split', axis=1)
|
||||
checks.remove('div_too_big_and_pre_split')
|
||||
|
||||
div_status_df = div_status_df.sort_index()
|
||||
|
||||
# Discard dividends with no problems
|
||||
@@ -2026,6 +2168,7 @@ class PriceHistory:
|
||||
# div_too_small_and_pre_split = 'div_too_small_and_pre_split' in row and row['div_too_small_and_pre_split'] # not happened yet
|
||||
# div_too_big_and_pre_split = 'div_too_big_and_pre_split' in row and row['div_too_big_and_pre_split'] # not happened yet
|
||||
div_date_wrong = 'div_date_wrong' in row and row['div_date_wrong']
|
||||
adj_too_small = 'adj_too_small' in row and row['adj_too_small']
|
||||
n_failed_checks = np.sum([row[c] for c in checks if c in row])
|
||||
|
||||
if div_too_big and adj_exceeds_prices and n_failed_checks == 2:
|
||||
@@ -2191,23 +2334,13 @@ class PriceHistory:
|
||||
cluster.loc[dt, 'Fixed?'] = True
|
||||
|
||||
elif div_too_big and div_exceeds_adj:
|
||||
div = row['div']
|
||||
close = div/row['%']
|
||||
adj_present = row['present adj']
|
||||
# Adj Close is correct, just need to fix Dividend.
|
||||
# Probably just a currency unit mixup.
|
||||
df2.loc[dt, 'Dividends'] /= currency_divide
|
||||
k = 'too-big div'
|
||||
if 'FX was repaired' in row and row['FX was repaired']:
|
||||
# Complication: not just a currency unit mixup, but
|
||||
# mixed up the local currency with $. So need to
|
||||
# recalculate adjustment.
|
||||
msg = None
|
||||
div_adj = 1.0 - (row['%']/currency_divide)
|
||||
adj_correction = div_adj / row['present adj']
|
||||
df2.loc[ :enddt, 'Adj Close'] *= adj_correction
|
||||
df2.loc[ :enddt, 'Repaired?'] = True
|
||||
df2_nan.loc[:enddt, 'Adj Close'] *= adj_correction
|
||||
df2_nan.loc[:enddt, 'Repaired?'] = True
|
||||
# Currently not logging this FX-fix event, since I refactored fixing.
|
||||
k += " and FX mixup"
|
||||
k = 'div-too-big'
|
||||
div_repairs.setdefault(k, []).append(dt)
|
||||
cluster.loc[dt, 'Fixed?'] = True
|
||||
|
||||
@@ -2227,6 +2360,68 @@ class PriceHistory:
|
||||
df2_nan.loc[:enddt, 'Repaired?'] = True
|
||||
cluster.loc[dt, 'Fixed?'] = True
|
||||
|
||||
elif div_too_small and adj_exceeds_div:
|
||||
# Adj Close is correct, just need to fix Dividend.
|
||||
# Probably just a currency unit mixup.
|
||||
df2.loc[dt, 'Dividends'] *= currency_divide
|
||||
k = 'too-small div'
|
||||
if 'FX was repaired' in row and row['FX was repaired']:
|
||||
# Complication: not just a currency unit mixup, but
|
||||
# mixed up the local currency with $. So need to
|
||||
# recalculate adjustment.
|
||||
msg = None
|
||||
div_adj = 1.0 - (row['%']*currency_divide)
|
||||
adj_correction = div_adj / row['present adj']
|
||||
df2.loc[ :enddt, 'Adj Close'] *= adj_correction
|
||||
df2.loc[ :enddt, 'Repaired?'] = True
|
||||
df2_nan.loc[:enddt, 'Adj Close'] *= adj_correction
|
||||
df2_nan.loc[:enddt, 'Repaired?'] = True
|
||||
# Currently not logging this FX-fix event, since I refactored fixing.
|
||||
k += " and FX mixup"
|
||||
div_repairs.setdefault(k, []).append(dt)
|
||||
cluster.loc[dt, 'Fixed?'] = True
|
||||
|
||||
elif n_failed_checks == 3:
|
||||
if div_too_big and div_exceeds_adj and div_pre_split:
|
||||
k = 'too-big div & pre-split'
|
||||
correction = (1.0/currency_divide) * (1.0/df2['Stock Splits'].loc[dt])
|
||||
correct_div = row['div'] * correction
|
||||
df2.loc[dt, 'Dividends'] = correct_div
|
||||
|
||||
target_div_pct = row['%'] * correction
|
||||
target_adj = 1.0 - target_div_pct
|
||||
present_adj = row['present adj']
|
||||
# Also correct adjustment to match corrected dividend
|
||||
k += ' & div-adjust'
|
||||
adj_correction = target_adj / present_adj
|
||||
df2.loc[ :enddt, 'Adj Close'] *= adj_correction
|
||||
df2.loc[ :enddt, 'Repaired?'] = True
|
||||
df2_nan.loc[:enddt, 'Adj Close'] *= adj_correction
|
||||
df2_nan.loc[:enddt, 'Repaired?'] = True
|
||||
cluster.loc[dt, 'Fixed?'] = True
|
||||
div_repairs.setdefault(k, []).append(dt)
|
||||
|
||||
elif div_too_big and div_exceeds_adj and adj_too_small:
|
||||
# Need to fix dividend AND adj close.
|
||||
# Probably just a currency unit mixup.
|
||||
div = row['div']
|
||||
close = div/row['%']
|
||||
adj_present = row['present adj']
|
||||
k = 'div-too-big and adj-too-small'
|
||||
#
|
||||
div_true = div/currency_divide
|
||||
pct_true = div_true / close
|
||||
df2.loc[dt, 'Dividends'] = div_true
|
||||
#
|
||||
adj_correct = 1.0 - pct_true
|
||||
adj_correction = adj_correct / adj_present
|
||||
df2.loc[ :enddt, 'Adj Close'] *= adj_correction
|
||||
df2.loc[ :enddt, 'Repaired?'] = True
|
||||
df2_nan.loc[:enddt, 'Adj Close'] *= adj_correction
|
||||
df2_nan.loc[:enddt, 'Repaired?'] = True
|
||||
div_repairs.setdefault(k, []).append(dt)
|
||||
cluster.loc[dt, 'Fixed?'] = True
|
||||
|
||||
if cluster.empty:
|
||||
continue
|
||||
|
||||
@@ -2390,7 +2585,12 @@ class PriceHistory:
|
||||
|
||||
# Update: if a VERY large dividend is paid out, then can be mistaken for a 1:2 stock split.
|
||||
# Fix = use adjusted prices
|
||||
adj = df2['Adj Close'].to_numpy() / df2['Close'].to_numpy()
|
||||
f_zero = df2['Close'] == 0
|
||||
if f_zero.any():
|
||||
adj = np.ones(len(df2))
|
||||
adj[~f_zero] = df2['Adj Close'].to_numpy()[~f_zero] / df2['Close'].to_numpy()[~f_zero]
|
||||
else:
|
||||
adj = df2['Adj Close'].to_numpy() / df2['Close'].to_numpy()
|
||||
df_dtype = price_data.dtype
|
||||
if df_dtype == np.int64:
|
||||
price_data = price_data.astype('float')
|
||||
@@ -2482,14 +2682,14 @@ class PriceHistory:
|
||||
|
||||
r = _1d_change_x / split_rcp
|
||||
f_down = _1d_change_x < 1.0 / threshold
|
||||
if f_down.any():
|
||||
# Discard where triggered by negative Adj Close after dividend
|
||||
f_neg = _1d_change_x < 0.0
|
||||
f_div = (df2['Dividends']>0).to_numpy()
|
||||
f_div_before = np.roll(f_div, 1)
|
||||
if f_down.ndim == 2:
|
||||
f_div_before = f_div_before[:, np.newaxis].repeat(f_down.shape[1], axis=1)
|
||||
f_down = f_down & ~(f_neg + f_div_before)
|
||||
# if f_down.any():
|
||||
# # Discard where triggered by negative Adj Close after dividend
|
||||
# f_neg = _1d_change_x < 0.0
|
||||
# f_div = (df2['Dividends']>0).to_numpy()
|
||||
# f_div_before = np.roll(f_div, 1)
|
||||
# if f_down.ndim == 2:
|
||||
# f_div_before = f_div_before[:, np.newaxis].repeat(f_down.shape[1], axis=1)
|
||||
# f_down = f_down & ~(f_neg + f_div_before)
|
||||
f_up = _1d_change_x > threshold
|
||||
f_up_ndims = len(f_up.shape)
|
||||
f_up_shifts = f_up if f_up_ndims==1 else f_up.any(axis=1)
|
||||
@@ -2512,7 +2712,7 @@ class PriceHistory:
|
||||
# assume false positive
|
||||
continue
|
||||
avg_vol_after = df2['Volume'].iloc[lookback:i-1].mean()
|
||||
if not np.isnan(avg_vol_after) and v/avg_vol_after < 2.0:
|
||||
if not np.isnan(avg_vol_after) and avg_vol_after > 0 and v/avg_vol_after < 2.0:
|
||||
# volume spike is actually a step-change, so
|
||||
# probably missing stock split
|
||||
continue
|
||||
@@ -2559,7 +2759,13 @@ class PriceHistory:
|
||||
threshold = _dateutil.relativedelta.relativedelta(days=threshold_days)
|
||||
else:
|
||||
threshold = _datetime.timedelta(days=threshold_days)
|
||||
if gap_td < threshold:
|
||||
if isinstance(threshold, _dateutil.relativedelta.relativedelta) and isinstance(gap_td, _dateutil.relativedelta.relativedelta):
|
||||
idx = np.where(gaps==gap_min)[0][0]
|
||||
dt = df2.index[idx]
|
||||
within_threshold = (dt + gap_td) < (dt + threshold)
|
||||
else:
|
||||
within_threshold = gap_td < threshold
|
||||
if within_threshold:
|
||||
logger.info('100x changes are too soon after stock split events, aborting', extra=log_extras)
|
||||
return df
|
||||
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
# from io import StringIO
|
||||
|
||||
import curl_cffi
|
||||
import pandas as pd
|
||||
import requests
|
||||
import warnings
|
||||
|
||||
from yfinance import utils
|
||||
from yfinance.const import _BASE_URL_, _SENTINEL_
|
||||
from yfinance.data import YfData
|
||||
from yfinance.const import _BASE_URL_
|
||||
from yfinance.exceptions import YFDataException
|
||||
|
||||
_QUOTE_SUMMARY_URL_ = f"{_BASE_URL_}/v10/finance/quoteSummary/"
|
||||
|
||||
_QUOTE_SUMMARY_URL_ = f"{_BASE_URL_}/v10/finance/quoteSummary"
|
||||
|
||||
class Holders:
|
||||
_SCRAPE_URL_ = 'https://finance.yahoo.com/quote'
|
||||
|
||||
def __init__(self, data: YfData, symbol: str, proxy=None):
|
||||
def __init__(self, data: YfData, symbol: str, proxy=_SENTINEL_):
|
||||
self._data = data
|
||||
self._symbol = symbol
|
||||
self.proxy = proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
data._set_proxy(proxy)
|
||||
|
||||
self._major = None
|
||||
self._major_direct_holders = None
|
||||
@@ -31,56 +31,50 @@ class Holders:
|
||||
@property
|
||||
def major(self) -> pd.DataFrame:
|
||||
if self._major is None:
|
||||
# self._scrape(self.proxy)
|
||||
self._fetch_and_parse()
|
||||
return self._major
|
||||
|
||||
@property
|
||||
def institutional(self) -> pd.DataFrame:
|
||||
if self._institutional is None:
|
||||
# self._scrape(self.proxy)
|
||||
self._fetch_and_parse()
|
||||
return self._institutional
|
||||
|
||||
@property
|
||||
def mutualfund(self) -> pd.DataFrame:
|
||||
if self._mutualfund is None:
|
||||
# self._scrape(self.proxy)
|
||||
self._fetch_and_parse()
|
||||
return self._mutualfund
|
||||
|
||||
@property
|
||||
def insider_transactions(self) -> pd.DataFrame:
|
||||
if self._insider_transactions is None:
|
||||
# self._scrape_insider_transactions(self.proxy)
|
||||
self._fetch_and_parse()
|
||||
return self._insider_transactions
|
||||
|
||||
@property
|
||||
def insider_purchases(self) -> pd.DataFrame:
|
||||
if self._insider_purchases is None:
|
||||
# self._scrape_insider_transactions(self.proxy)
|
||||
self._fetch_and_parse()
|
||||
return self._insider_purchases
|
||||
|
||||
@property
|
||||
def insider_roster(self) -> pd.DataFrame:
|
||||
if self._insider_roster is None:
|
||||
# self._scrape_insider_ros(self.proxy)
|
||||
self._fetch_and_parse()
|
||||
return self._insider_roster
|
||||
|
||||
def _fetch(self, proxy):
|
||||
def _fetch(self):
|
||||
modules = ','.join(
|
||||
["institutionOwnership", "fundOwnership", "majorDirectHolders", "majorHoldersBreakdown", "insiderTransactions", "insiderHolders", "netSharePurchaseActivity"])
|
||||
params_dict = {"modules": modules, "corsDomain": "finance.yahoo.com", "formatted": "false"}
|
||||
result = self._data.get_raw_json(f"{_QUOTE_SUMMARY_URL_}/{self._symbol}", user_agent_headers=self._data.user_agent_headers, params=params_dict, proxy=proxy)
|
||||
result = self._data.get_raw_json(f"{_QUOTE_SUMMARY_URL_}/{self._symbol}", params=params_dict)
|
||||
return result
|
||||
|
||||
def _fetch_and_parse(self):
|
||||
try:
|
||||
result = self._fetch(self.proxy)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
result = self._fetch()
|
||||
except curl_cffi.requests.exceptions.HTTPError as e:
|
||||
utils.get_yf_logger().error(str(e))
|
||||
|
||||
self._major = pd.DataFrame()
|
||||
@@ -187,8 +181,10 @@ class Holders:
|
||||
del owner["maxAge"]
|
||||
df = pd.DataFrame(holders)
|
||||
if not df.empty:
|
||||
df["positionDirectDate"] = pd.to_datetime(df["positionDirectDate"], unit="s")
|
||||
df["latestTransDate"] = pd.to_datetime(df["latestTransDate"], unit="s")
|
||||
if "positionDirectDate" in df:
|
||||
df["positionDirectDate"] = pd.to_datetime(df["positionDirectDate"], unit="s")
|
||||
if "latestTransDate" in df:
|
||||
df["latestTransDate"] = pd.to_datetime(df["latestTransDate"], unit="s")
|
||||
|
||||
df.rename(columns={
|
||||
"name": "Name",
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import curl_cffi
|
||||
import datetime
|
||||
import json
|
||||
|
||||
import numpy as _np
|
||||
import pandas as pd
|
||||
import requests
|
||||
import warnings
|
||||
|
||||
from yfinance import utils
|
||||
from yfinance.const import quote_summary_valid_modules, _BASE_URL_, _QUERY1_URL_, _SENTINEL_
|
||||
from yfinance.data import YfData
|
||||
from yfinance.const import quote_summary_valid_modules, _BASE_URL_
|
||||
from yfinance.exceptions import YFDataException, YFException
|
||||
|
||||
info_retired_keys_price = {"currentPrice", "dayHigh", "dayLow", "open", "previousClose", "volume", "volume24Hr"}
|
||||
@@ -26,9 +26,11 @@ _QUOTE_SUMMARY_URL_ = f"{_BASE_URL_}/v10/finance/quoteSummary"
|
||||
class FastInfo:
|
||||
# Contain small subset of info[] items that can be fetched faster elsewhere.
|
||||
# Imitates a dict.
|
||||
def __init__(self, tickerBaseObject, proxy=None):
|
||||
def __init__(self, tickerBaseObject, proxy=_SENTINEL_):
|
||||
self._tkr = tickerBaseObject
|
||||
self.proxy = proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._tkr._data._set_proxy(proxy)
|
||||
|
||||
self._prices_1y = None
|
||||
self._prices_1wk_1h_prepost = None
|
||||
@@ -128,8 +130,8 @@ class FastInfo:
|
||||
|
||||
def _get_1y_prices(self, fullDaysOnly=False):
|
||||
if self._prices_1y is None:
|
||||
self._prices_1y = self._tkr.history(period="1y", auto_adjust=False, keepna=True, proxy=self.proxy)
|
||||
self._md = self._tkr.get_history_metadata(proxy=self.proxy)
|
||||
self._prices_1y = self._tkr.history(period="1y", auto_adjust=False, keepna=True)
|
||||
self._md = self._tkr.get_history_metadata()
|
||||
try:
|
||||
ctp = self._md["currentTradingPeriod"]
|
||||
self._today_open = pd.to_datetime(ctp["regular"]["start"], unit='s', utc=True).tz_convert(self.timezone)
|
||||
@@ -154,12 +156,12 @@ class FastInfo:
|
||||
|
||||
def _get_1wk_1h_prepost_prices(self):
|
||||
if self._prices_1wk_1h_prepost is None:
|
||||
self._prices_1wk_1h_prepost = self._tkr.history(period="5d", interval="1h", auto_adjust=False, prepost=True, proxy=self.proxy)
|
||||
self._prices_1wk_1h_prepost = self._tkr.history(period="5d", interval="1h", auto_adjust=False, prepost=True)
|
||||
return self._prices_1wk_1h_prepost
|
||||
|
||||
def _get_1wk_1h_reg_prices(self):
|
||||
if self._prices_1wk_1h_reg is None:
|
||||
self._prices_1wk_1h_reg = self._tkr.history(period="5d", interval="1h", auto_adjust=False, prepost=False, proxy=self.proxy)
|
||||
self._prices_1wk_1h_reg = self._tkr.history(period="5d", interval="1h", auto_adjust=False, prepost=False)
|
||||
return self._prices_1wk_1h_reg
|
||||
|
||||
def _get_exchange_metadata(self):
|
||||
@@ -167,7 +169,7 @@ class FastInfo:
|
||||
return self._md
|
||||
|
||||
self._get_1y_prices()
|
||||
self._md = self._tkr.get_history_metadata(proxy=self.proxy)
|
||||
self._md = self._tkr.get_history_metadata()
|
||||
return self._md
|
||||
|
||||
def _exchange_open_now(self):
|
||||
@@ -198,7 +200,7 @@ class FastInfo:
|
||||
if self._currency is not None:
|
||||
return self._currency
|
||||
|
||||
md = self._tkr.get_history_metadata(proxy=self.proxy)
|
||||
md = self._tkr.get_history_metadata()
|
||||
self._currency = md["currency"]
|
||||
return self._currency
|
||||
|
||||
@@ -207,7 +209,7 @@ class FastInfo:
|
||||
if self._quote_type is not None:
|
||||
return self._quote_type
|
||||
|
||||
md = self._tkr.get_history_metadata(proxy=self.proxy)
|
||||
md = self._tkr.get_history_metadata()
|
||||
self._quote_type = md["instrumentType"]
|
||||
return self._quote_type
|
||||
|
||||
@@ -232,7 +234,7 @@ class FastInfo:
|
||||
if self._shares is not None:
|
||||
return self._shares
|
||||
|
||||
shares = self._tkr.get_shares_full(start=pd.Timestamp.utcnow().date()-pd.Timedelta(days=548), proxy=self.proxy)
|
||||
shares = self._tkr.get_shares_full(start=pd.Timestamp.utcnow().date()-pd.Timedelta(days=548))
|
||||
# if shares is None:
|
||||
# # Requesting 18 months failed, so fallback to shares which should include last year
|
||||
# shares = self._tkr.get_shares()
|
||||
@@ -484,11 +486,12 @@ class FastInfo:
|
||||
|
||||
|
||||
class Quote:
|
||||
|
||||
def __init__(self, data: YfData, symbol: str, proxy=None):
|
||||
def __init__(self, data: YfData, symbol: str, proxy=_SENTINEL_):
|
||||
self._data = data
|
||||
self._symbol = symbol
|
||||
self.proxy = proxy
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
self._info = None
|
||||
self._retired_info = None
|
||||
@@ -505,15 +508,15 @@ class Quote:
|
||||
@property
|
||||
def info(self) -> dict:
|
||||
if self._info is None:
|
||||
self._fetch_info(self.proxy)
|
||||
self._fetch_complementary(self.proxy)
|
||||
self._fetch_info()
|
||||
self._fetch_complementary()
|
||||
|
||||
return self._info
|
||||
|
||||
@property
|
||||
def sustainability(self) -> pd.DataFrame:
|
||||
if self._sustainability is None:
|
||||
result = self._fetch(self.proxy, modules=['esgScores'])
|
||||
result = self._fetch(modules=['esgScores'])
|
||||
if result is None:
|
||||
self._sustainability = pd.DataFrame()
|
||||
else:
|
||||
@@ -527,7 +530,7 @@ class Quote:
|
||||
@property
|
||||
def recommendations(self) -> pd.DataFrame:
|
||||
if self._recommendations is None:
|
||||
result = self._fetch(self.proxy, modules=['recommendationTrend'])
|
||||
result = self._fetch(modules=['recommendationTrend'])
|
||||
if result is None:
|
||||
self._recommendations = pd.DataFrame()
|
||||
else:
|
||||
@@ -541,7 +544,7 @@ class Quote:
|
||||
@property
|
||||
def upgrades_downgrades(self) -> pd.DataFrame:
|
||||
if self._upgrades_downgrades is None:
|
||||
result = self._fetch(self.proxy, modules=['upgradeDowngradeHistory'])
|
||||
result = self._fetch(modules=['upgradeDowngradeHistory'])
|
||||
if result is None:
|
||||
self._upgrades_downgrades = pd.DataFrame()
|
||||
else:
|
||||
@@ -575,7 +578,7 @@ class Quote:
|
||||
def valid_modules():
|
||||
return quote_summary_valid_modules
|
||||
|
||||
def _fetch(self, proxy, modules: list):
|
||||
def _fetch(self, modules: list):
|
||||
if not isinstance(modules, list):
|
||||
raise YFException("Should provide a list of modules, see available modules using `valid_modules`")
|
||||
|
||||
@@ -584,39 +587,61 @@ class Quote:
|
||||
raise YFException("No valid modules provided, see available modules using `valid_modules`")
|
||||
params_dict = {"modules": modules, "corsDomain": "finance.yahoo.com", "formatted": "false", "symbol": self._symbol}
|
||||
try:
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_ + f"/{self._symbol}", user_agent_headers=self._data.user_agent_headers, params=params_dict, proxy=proxy)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
result = self._data.get_raw_json(_QUOTE_SUMMARY_URL_ + f"/{self._symbol}", params=params_dict)
|
||||
except curl_cffi.requests.exceptions.HTTPError as e:
|
||||
utils.get_yf_logger().error(str(e))
|
||||
return None
|
||||
return result
|
||||
|
||||
def _fetch_info(self, proxy):
|
||||
def _fetch_additional_info(self):
|
||||
params_dict = {"symbols": self._symbol, "formatted": "false"}
|
||||
try:
|
||||
result = self._data.get_raw_json(f"{_QUERY1_URL_}/v7/finance/quote?", params=params_dict)
|
||||
except curl_cffi.requests.exceptions.HTTPError as e:
|
||||
utils.get_yf_logger().error(str(e))
|
||||
return None
|
||||
return result
|
||||
|
||||
def _fetch_info(self):
|
||||
if self._already_fetched:
|
||||
return
|
||||
self._already_fetched = True
|
||||
modules = ['financialData', 'quoteType', 'defaultKeyStatistics', 'assetProfile', 'summaryDetail']
|
||||
result = self._fetch(proxy, modules=modules)
|
||||
if result is None:
|
||||
self._info = {}
|
||||
return
|
||||
result = self._fetch(modules=modules)
|
||||
additional_info = self._fetch_additional_info()
|
||||
if additional_info is not None and result is not None:
|
||||
result.update(additional_info)
|
||||
else:
|
||||
result = additional_info
|
||||
|
||||
query1_info = {}
|
||||
for quote in ["quoteSummary", "quoteResponse"]:
|
||||
if quote in result and len(result[quote]["result"]) > 0:
|
||||
result[quote]["result"][0]["symbol"] = self._symbol
|
||||
query_info = next(
|
||||
(info for info in result.get(quote, {}).get("result", [])
|
||||
if info["symbol"] == self._symbol),
|
||||
None,
|
||||
)
|
||||
if query_info:
|
||||
query1_info.update(query_info)
|
||||
|
||||
# Normalize and flatten nested dictionaries while converting maxAge from days (1) to seconds (86400).
|
||||
# This handles Yahoo Finance API inconsistency where maxAge is sometimes expressed in days instead of seconds.
|
||||
processed_info = {}
|
||||
for k, v in query1_info.items():
|
||||
|
||||
# Handle nested dictionary
|
||||
if isinstance(v, dict):
|
||||
for k1, v1 in v.items():
|
||||
if v1 is not None:
|
||||
processed_info[k1] = 86400 if k1 == "maxAge" and v1 == 1 else v1
|
||||
|
||||
elif v is not None:
|
||||
processed_info[k] = v
|
||||
|
||||
query1_info = processed_info
|
||||
|
||||
result["quoteSummary"]["result"][0]["symbol"] = self._symbol
|
||||
query1_info = next(
|
||||
(info for info in result.get("quoteSummary", {}).get("result", []) if info["symbol"] == self._symbol),
|
||||
None,
|
||||
)
|
||||
# Most keys that appear in multiple dicts have same value. Except 'maxAge' because
|
||||
# Yahoo not consistent with days vs seconds. Fix it here:
|
||||
for k in query1_info:
|
||||
if "maxAge" in query1_info[k] and query1_info[k]["maxAge"] == 1:
|
||||
query1_info[k]["maxAge"] = 86400
|
||||
query1_info = {
|
||||
k1: v1
|
||||
for k, v in query1_info.items()
|
||||
if isinstance(v, dict)
|
||||
for k1, v1 in v.items()
|
||||
if v1
|
||||
}
|
||||
# recursively format but only because of 'companyOfficers'
|
||||
|
||||
def _format(k, v):
|
||||
@@ -631,17 +656,15 @@ class Quote:
|
||||
else:
|
||||
v2 = v
|
||||
return v2
|
||||
for k, v in query1_info.items():
|
||||
query1_info[k] = _format(k, v)
|
||||
self._info = query1_info
|
||||
|
||||
def _fetch_complementary(self, proxy):
|
||||
self._info = {k: _format(k, v) for k, v in query1_info.items()}
|
||||
|
||||
def _fetch_complementary(self):
|
||||
if self._already_fetched_complementary:
|
||||
return
|
||||
self._already_fetched_complementary = True
|
||||
|
||||
# self._scrape(proxy) # decrypt broken
|
||||
self._fetch_info(proxy)
|
||||
self._fetch_info()
|
||||
if self._info is None:
|
||||
return
|
||||
|
||||
@@ -654,7 +677,7 @@ class Quote:
|
||||
# p = _re.compile(r'root\.App\.main = (.*);')
|
||||
# url = 'https://finance.yahoo.com/quote/{}/key-statistics?p={}'.format(self._ticker.ticker, self._ticker.ticker)
|
||||
# try:
|
||||
# r = session.get(url, headers=utils.user_agent_headers)
|
||||
# r = session.get(url)
|
||||
# data = _json.loads(p.findall(r.text)[0])
|
||||
# key_stats = data['context']['dispatcher']['stores']['QuoteTimeSeriesStore']["timeSeries"]
|
||||
# for k in keys:
|
||||
@@ -680,7 +703,7 @@ class Quote:
|
||||
end = int(end.timestamp())
|
||||
url += f"&period1={start}&period2={end}"
|
||||
|
||||
json_str = self._data.cache_get(url=url, proxy=proxy).text
|
||||
json_str = self._data.cache_get(url=url).text
|
||||
json_data = json.loads(json_str)
|
||||
json_result = json_data.get("timeseries") or json_data.get("finance")
|
||||
if json_result["error"] is not None:
|
||||
@@ -694,7 +717,7 @@ class Quote:
|
||||
|
||||
def _fetch_calendar(self):
|
||||
# secFilings return too old data, so not requesting it for now
|
||||
result = self._fetch(self.proxy, modules=['calendarEvents'])
|
||||
result = self._fetch(modules=['calendarEvents'])
|
||||
if result is None:
|
||||
self._calendar = {}
|
||||
return
|
||||
@@ -721,7 +744,7 @@ class Quote:
|
||||
|
||||
|
||||
def _fetch_sec_filings(self):
|
||||
result = self._fetch(self.proxy, modules=['secFilings'])
|
||||
result = self._fetch(modules=['secFilings'])
|
||||
if result is None:
|
||||
return None
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import curl_cffi
|
||||
from typing import Union
|
||||
import warnings
|
||||
|
||||
from yfinance.const import _QUERY1_URL_, _SENTINEL_
|
||||
from yfinance.data import YfData
|
||||
from ..utils import dynamic_docstring, generate_list_table_from_dict_universal
|
||||
|
||||
from .query import EquityQuery as EqyQy
|
||||
from .query import FundQuery as FndQy
|
||||
from .query import QueryBase, EquityQuery, FundQuery
|
||||
|
||||
from yfinance.const import _BASE_URL_
|
||||
from yfinance.data import YfData
|
||||
|
||||
from ..utils import dynamic_docstring, generate_list_table_from_dict_universal
|
||||
|
||||
from typing import Union
|
||||
import requests
|
||||
|
||||
_SCREENER_URL_ = f"{_BASE_URL_}/v1/finance/screener"
|
||||
_SCREENER_URL_ = f"{_QUERY1_URL_}/v1/finance/screener"
|
||||
_PREDEFINED_URL_ = f"{_SCREENER_URL_}/predefined/saved"
|
||||
|
||||
PREDEFINED_SCREENER_BODY_DEFAULTS = {
|
||||
"offset":0, "size":25, "userId":"","userIdType":"guid"
|
||||
"offset":0, "count":25, "userId":"","userIdType":"guid"
|
||||
}
|
||||
|
||||
PREDEFINED_SCREENER_QUERIES = {
|
||||
@@ -28,7 +28,7 @@ PREDEFINED_SCREENER_QUERIES = {
|
||||
"query": EqyQy('and', [EqyQy('gte', ['quarterlyrevenuegrowth.quarterly', 25]), EqyQy('gte', ['epsgrowth.lasttwelvemonths', 25]), EqyQy('eq', ['sector', 'Technology']), EqyQy('is-in', ['exchange', 'NMS', 'NYQ'])])},
|
||||
'most_actives': {"sortField":"dayvolume", "sortType":"DESC",
|
||||
"query": EqyQy('and', [EqyQy('eq', ['region', 'us']), EqyQy('gte', ['intradaymarketcap', 2000000000]), EqyQy('gt', ['dayvolume', 5000000])])},
|
||||
'most_shorted_stocks': {"size":25, "offset":0, "sortField":"short_percentage_of_shares_outstanding.value", "sortType":"DESC",
|
||||
'most_shorted_stocks': {"count":25, "offset":0, "sortField":"short_percentage_of_shares_outstanding.value", "sortType":"DESC",
|
||||
"query": EqyQy('and', [EqyQy('eq', ['region', 'us']), EqyQy('gt', ['intradayprice', 1]), EqyQy('gt', ['avgdailyvol3m', 200000])])},
|
||||
'small_cap_gainers': {"sortField":"eodvolume", "sortType":"desc",
|
||||
"query": EqyQy("and", [EqyQy("lt", ["intradaymarketcap",2000000000]), EqyQy("is-in", ["exchange", "NMS", "NYQ"])])},
|
||||
@@ -53,12 +53,13 @@ PREDEFINED_SCREENER_QUERIES = {
|
||||
@dynamic_docstring({"predefined_screeners": generate_list_table_from_dict_universal(PREDEFINED_SCREENER_QUERIES, bullets=True, title='Predefined queries (Dec-2024)')})
|
||||
def screen(query: Union[str, EquityQuery, FundQuery],
|
||||
offset: int = None,
|
||||
size: int = None,
|
||||
size: int = None,
|
||||
count: int = None,
|
||||
sortField: str = None,
|
||||
sortAsc: bool = None,
|
||||
userId: str = None,
|
||||
userIdType: str = None,
|
||||
session = None, proxy = None):
|
||||
session = None, proxy = _SENTINEL_):
|
||||
"""
|
||||
Run a screen: predefined query, or custom query.
|
||||
|
||||
@@ -71,6 +72,10 @@ def screen(query: Union[str, EquityQuery, FundQuery],
|
||||
The offset for the results. Default 0.
|
||||
size : int
|
||||
number of results to return. Default 100, maximum 250 (Yahoo)
|
||||
Use count instead for predefined queries.
|
||||
count : int
|
||||
number of results to return. Default 25, maximum 250 (Yahoo)
|
||||
Use size instead for custom queries.
|
||||
sortField : str
|
||||
field to sort by. Default "ticker"
|
||||
sortAsc : bool
|
||||
@@ -106,25 +111,43 @@ def screen(query: Union[str, EquityQuery, FundQuery],
|
||||
{predefined_screeners}
|
||||
"""
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
_data = YfData(session=session, proxy=proxy)
|
||||
else:
|
||||
_data = YfData(session=session)
|
||||
|
||||
# Only use defaults when user NOT give a predefined, because
|
||||
# Yahoo's predefined endpoint auto-applies defaults. Also,
|
||||
# that endpoint might be ignoring these fields.
|
||||
defaults = {
|
||||
'offset': 0,
|
||||
'size': 25,
|
||||
'count': 25,
|
||||
'sortField': 'ticker',
|
||||
'sortAsc': False,
|
||||
'userId': "",
|
||||
'userIdType': "guid"
|
||||
}
|
||||
|
||||
if count is not None and count > 250:
|
||||
raise ValueError("Yahoo limits query count to 250, reduce count.")
|
||||
|
||||
if size is not None and size > 250:
|
||||
raise ValueError("Yahoo limits query size to 250, reduce size.")
|
||||
|
||||
fields = dict(locals())
|
||||
for k in ['query', 'session', 'proxy']:
|
||||
if k in fields:
|
||||
del fields[k]
|
||||
if offset is not None and isinstance(query, str):
|
||||
# offset ignored by predefined API so switch to other API
|
||||
post_query = PREDEFINED_SCREENER_QUERIES[query]
|
||||
query = post_query['query']
|
||||
# use predefined's attributes if user not specified
|
||||
if sortField is None:
|
||||
sortField = post_query['sortField']
|
||||
if sortAsc is None:
|
||||
sortAsc = post_query['sortType'].lower() == 'asc'
|
||||
# and don't use defaults
|
||||
defaults = {}
|
||||
|
||||
fields = {'offset': offset, 'count': count, "size": size, 'sortField': sortField, 'sortAsc': sortAsc, 'userId': userId, 'userIdType': userIdType}
|
||||
|
||||
params_dict = {"corsDomain": "finance.yahoo.com", "formatted": "false", "lang": "en-US", "region": "US"}
|
||||
|
||||
@@ -132,15 +155,22 @@ def screen(query: Union[str, EquityQuery, FundQuery],
|
||||
if isinstance(query, str):
|
||||
# post_query = PREDEFINED_SCREENER_QUERIES[query]
|
||||
# Switch to Yahoo's predefined endpoint
|
||||
_data = YfData(session=session)
|
||||
|
||||
if size is not None:
|
||||
warnings.warn("Screen 'size' argument is deprecated for predefined screens, set 'count' instead.", DeprecationWarning, stacklevel=2)
|
||||
count = size
|
||||
size = None
|
||||
fields['count'] = fields['size']
|
||||
del fields['size']
|
||||
|
||||
params_dict['scrIds'] = query
|
||||
for k,v in fields.items():
|
||||
if v is not None:
|
||||
params_dict[k] = v
|
||||
resp = _data.get(url=_PREDEFINED_URL_, params=params_dict, proxy=proxy)
|
||||
resp = _data.get(url=_PREDEFINED_URL_, params=params_dict)
|
||||
try:
|
||||
resp.raise_for_status()
|
||||
except requests.exceptions.HTTPError:
|
||||
except curl_cffi.requests.exceptions.HTTPError:
|
||||
if query not in PREDEFINED_SCREENER_QUERIES:
|
||||
print(f"yfinance.screen: '{query}' is probably not a predefined query.")
|
||||
raise
|
||||
@@ -170,11 +200,8 @@ def screen(query: Union[str, EquityQuery, FundQuery],
|
||||
post_query['query'] = post_query['query'].to_dict()
|
||||
|
||||
# Fetch
|
||||
_data = YfData(session=session)
|
||||
response = _data.post(_SCREENER_URL_,
|
||||
body=post_query,
|
||||
user_agent_headers=_data.user_agent_headers,
|
||||
params=params_dict,
|
||||
proxy=proxy)
|
||||
params=params_dict)
|
||||
response.raise_for_status()
|
||||
return response.json()['finance']['result'][0]
|
||||
|
||||
@@ -20,16 +20,17 @@
|
||||
#
|
||||
|
||||
import json as _json
|
||||
import warnings
|
||||
|
||||
from . import utils
|
||||
from .const import _BASE_URL_
|
||||
from .const import _BASE_URL_, _SENTINEL_
|
||||
from .data import YfData
|
||||
|
||||
|
||||
class Search:
|
||||
def __init__(self, query, max_results=8, news_count=8, lists_count=8, include_cb=True, include_nav_links=False,
|
||||
include_research=False, include_cultural_assets=False, enable_fuzzy_query=False, recommended=8,
|
||||
session=None, proxy=None, timeout=30, raise_errors=True):
|
||||
session=None, proxy=_SENTINEL_, timeout=30, raise_errors=True):
|
||||
"""
|
||||
Fetches and organizes search results from Yahoo Finance, including stock quotes and news articles.
|
||||
|
||||
@@ -45,16 +46,20 @@ class Search:
|
||||
enable_fuzzy_query: Enable fuzzy search for typos (default False).
|
||||
recommended: Recommended number of results to return (default 8).
|
||||
session: Custom HTTP session for requests (default None).
|
||||
proxy: Proxy settings for requests (default None).
|
||||
timeout: Request timeout in seconds (default 30).
|
||||
raise_errors: Raise exceptions on error (default True).
|
||||
"""
|
||||
self.session = session
|
||||
self._data = YfData(session=self.session)
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
|
||||
self.query = query
|
||||
self.max_results = max_results
|
||||
self.enable_fuzzy_query = enable_fuzzy_query
|
||||
self.news_count = news_count
|
||||
self.session = session
|
||||
self.proxy = proxy
|
||||
self.timeout = timeout
|
||||
self.raise_errors = raise_errors
|
||||
|
||||
@@ -65,7 +70,6 @@ class Search:
|
||||
self.enable_cultural_assets = include_cultural_assets
|
||||
self.recommended = recommended
|
||||
|
||||
self._data = YfData(session=self.session)
|
||||
self._logger = utils.get_yf_logger()
|
||||
|
||||
self._response = {}
|
||||
@@ -98,7 +102,7 @@ class Search:
|
||||
|
||||
self._logger.debug(f'{self.query}: Yahoo GET parameters: {str(dict(params))}')
|
||||
|
||||
data = self._data.cache_get(url=url, params=params, proxy=self.proxy, timeout=self.timeout)
|
||||
data = self._data.cache_get(url=url, params=params, timeout=self.timeout)
|
||||
if data is None or "Will be right back" in data.text:
|
||||
raise RuntimeError("*** YAHOO! FINANCE IS CURRENTLY DOWN! ***\n"
|
||||
"Our engineers are working quickly to resolve "
|
||||
|
||||
@@ -22,17 +22,21 @@
|
||||
from __future__ import print_function
|
||||
|
||||
from collections import namedtuple as _namedtuple
|
||||
from .scrapers.funds import FundsData
|
||||
import warnings
|
||||
|
||||
import pandas as _pd
|
||||
|
||||
from .base import TickerBase
|
||||
from .const import _BASE_URL_
|
||||
from .const import _BASE_URL_, _SENTINEL_
|
||||
from .scrapers.funds import FundsData
|
||||
|
||||
|
||||
class Ticker(TickerBase):
|
||||
def __init__(self, ticker, session=None, proxy=None):
|
||||
super(Ticker, self).__init__(ticker, session=session, proxy=proxy)
|
||||
def __init__(self, ticker, session=None, proxy=_SENTINEL_):
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
super(Ticker, self).__init__(ticker, session=session)
|
||||
self._expirations = {}
|
||||
self._underlying = {}
|
||||
|
||||
@@ -45,7 +49,7 @@ class Ticker(TickerBase):
|
||||
else:
|
||||
url = f"{_BASE_URL_}/v7/finance/options/{self.ticker}?date={date}"
|
||||
|
||||
r = self._data.get(url=url, proxy=self.proxy).json()
|
||||
r = self._data.get(url=url).json()
|
||||
if len(r.get('optionChain', {}).get('result', [])) > 0:
|
||||
for exp in r['optionChain']['result'][0]['expirationDates']:
|
||||
self._expirations[_pd.Timestamp(exp, unit='s').strftime('%Y-%m-%d')] = exp
|
||||
@@ -201,6 +205,10 @@ class Ticker(TickerBase):
|
||||
def quarterly_income_stmt(self) -> _pd.DataFrame:
|
||||
return self.get_income_stmt(pretty=True, freq='quarterly')
|
||||
|
||||
@property
|
||||
def ttm_income_stmt(self) -> _pd.DataFrame:
|
||||
return self.get_income_stmt(pretty=True, freq='trailing')
|
||||
|
||||
@property
|
||||
def incomestmt(self) -> _pd.DataFrame:
|
||||
return self.income_stmt
|
||||
@@ -209,6 +217,10 @@ class Ticker(TickerBase):
|
||||
def quarterly_incomestmt(self) -> _pd.DataFrame:
|
||||
return self.quarterly_income_stmt
|
||||
|
||||
@property
|
||||
def ttm_incomestmt(self) -> _pd.DataFrame:
|
||||
return self.ttm_income_stmt
|
||||
|
||||
@property
|
||||
def financials(self) -> _pd.DataFrame:
|
||||
return self.income_stmt
|
||||
@@ -217,6 +229,10 @@ class Ticker(TickerBase):
|
||||
def quarterly_financials(self) -> _pd.DataFrame:
|
||||
return self.quarterly_income_stmt
|
||||
|
||||
@property
|
||||
def ttm_financials(self) -> _pd.DataFrame:
|
||||
return self.ttm_income_stmt
|
||||
|
||||
@property
|
||||
def balance_sheet(self) -> _pd.DataFrame:
|
||||
return self.get_balance_sheet(pretty=True)
|
||||
@@ -241,6 +257,10 @@ class Ticker(TickerBase):
|
||||
def quarterly_cash_flow(self) -> _pd.DataFrame:
|
||||
return self.get_cash_flow(pretty=True, freq='quarterly')
|
||||
|
||||
@property
|
||||
def ttm_cash_flow(self) -> _pd.DataFrame:
|
||||
return self.get_cash_flow(pretty=True, freq='trailing')
|
||||
|
||||
@property
|
||||
def cashflow(self) -> _pd.DataFrame:
|
||||
return self.cash_flow
|
||||
@@ -249,6 +269,10 @@ class Ticker(TickerBase):
|
||||
def quarterly_cashflow(self) -> _pd.DataFrame:
|
||||
return self.quarterly_cash_flow
|
||||
|
||||
@property
|
||||
def ttm_cashflow(self) -> _pd.DataFrame:
|
||||
return self.ttm_cash_flow
|
||||
|
||||
@property
|
||||
def analyst_price_targets(self) -> dict:
|
||||
return self.get_analyst_price_targets()
|
||||
@@ -301,4 +325,4 @@ class Ticker(TickerBase):
|
||||
|
||||
@property
|
||||
def funds_data(self) -> FundsData:
|
||||
return self.get_funds_data()
|
||||
return self.get_funds_data()
|
||||
|
||||
@@ -21,10 +21,12 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import warnings
|
||||
|
||||
from . import Ticker, multi
|
||||
|
||||
|
||||
# from collections import namedtuple as _namedtuple
|
||||
from .live import WebSocket
|
||||
from .data import YfData
|
||||
from .const import _SENTINEL_
|
||||
|
||||
|
||||
class Tickers:
|
||||
@@ -38,6 +40,11 @@ class Tickers:
|
||||
self.symbols = [ticker.upper() for ticker in tickers]
|
||||
self.tickers = {ticker: Ticker(ticker, session=session) for ticker in self.symbols}
|
||||
|
||||
self._data = YfData(session=session)
|
||||
|
||||
self._message_handler = None
|
||||
self.ws = None
|
||||
|
||||
# self.tickers = _namedtuple(
|
||||
# "Tickers", ticker_objects.keys(), rename=True
|
||||
# )(*ticker_objects.values())
|
||||
@@ -45,10 +52,15 @@ class Tickers:
|
||||
def history(self, period="1mo", interval="1d",
|
||||
start=None, end=None, prepost=False,
|
||||
actions=True, auto_adjust=True, repair=False,
|
||||
proxy=None,
|
||||
proxy=_SENTINEL_,
|
||||
threads=True, group_by='column', progress=True,
|
||||
timeout=10, **kwargs):
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
proxy = _SENTINEL_
|
||||
|
||||
return self.download(
|
||||
period, interval,
|
||||
start, end, prepost,
|
||||
@@ -60,10 +72,15 @@ class Tickers:
|
||||
def download(self, period="1mo", interval="1d",
|
||||
start=None, end=None, prepost=False,
|
||||
actions=True, auto_adjust=True, repair=False,
|
||||
proxy=None,
|
||||
proxy=_SENTINEL_,
|
||||
threads=True, group_by='column', progress=True,
|
||||
timeout=10, **kwargs):
|
||||
|
||||
if proxy is not _SENTINEL_:
|
||||
warnings.warn("Set proxy via new config function: yf.set_config(proxy=proxy)", DeprecationWarning, stacklevel=2)
|
||||
self._data._set_proxy(proxy)
|
||||
proxy = _SENTINEL_
|
||||
|
||||
data = multi.download(self.symbols,
|
||||
start=start, end=end,
|
||||
actions=actions,
|
||||
@@ -72,7 +89,6 @@ class Tickers:
|
||||
period=period,
|
||||
interval=interval,
|
||||
prepost=prepost,
|
||||
proxy=proxy,
|
||||
group_by='ticker',
|
||||
threads=threads,
|
||||
progress=progress,
|
||||
@@ -90,3 +106,10 @@ class Tickers:
|
||||
|
||||
def news(self):
|
||||
return {ticker: [item for item in Ticker(ticker).news] for ticker in self.symbols}
|
||||
|
||||
def live(self, message_handler=None, verbose=True):
|
||||
self._message_handler = message_handler
|
||||
|
||||
self.ws = WebSocket(verbose=verbose)
|
||||
self.ws.subscribe(self.symbols)
|
||||
self.ws.listen(self._message_handler)
|
||||
|
||||
@@ -27,7 +27,7 @@ import re
|
||||
import re as _re
|
||||
import sys as _sys
|
||||
import threading
|
||||
from functools import lru_cache, wraps
|
||||
from functools import wraps
|
||||
from inspect import getmembers
|
||||
from types import FunctionType
|
||||
from typing import List, Optional
|
||||
@@ -35,16 +35,11 @@ from typing import List, Optional
|
||||
import numpy as _np
|
||||
import pandas as _pd
|
||||
import pytz as _tz
|
||||
import requests as _requests
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from pytz import UnknownTimeZoneError
|
||||
|
||||
from yfinance import const
|
||||
|
||||
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'}
|
||||
|
||||
|
||||
# From https://stackoverflow.com/a/59128615
|
||||
def attributes(obj):
|
||||
disallowed_names = {
|
||||
@@ -55,13 +50,6 @@ def attributes(obj):
|
||||
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
|
||||
|
||||
|
||||
@lru_cache(maxsize=20)
|
||||
def print_once(msg):
|
||||
# 'warnings' module suppression of repeat messages does not work.
|
||||
# This function replicates correct behaviour
|
||||
print(msg)
|
||||
|
||||
|
||||
# Logging
|
||||
# Note: most of this logic is adding indentation with function depth,
|
||||
# so that DEBUG log is readable.
|
||||
@@ -186,15 +174,14 @@ def is_isin(string):
|
||||
return bool(_re.match("^([A-Z]{2})([A-Z0-9]{9})([0-9])$", string))
|
||||
|
||||
|
||||
def get_all_by_isin(isin, proxy=None, session=None):
|
||||
def get_all_by_isin(isin):
|
||||
if not (is_isin(isin)):
|
||||
raise ValueError("Invalid ISIN number")
|
||||
|
||||
# Deferred this to prevent circular imports
|
||||
from .search import Search
|
||||
|
||||
session = session or _requests
|
||||
search = Search(query=isin, max_results=1, session=session, proxy=proxy)
|
||||
search = Search(query=isin, max_results=1)
|
||||
|
||||
# Extract the first quote and news
|
||||
ticker = search.quotes[0] if search.quotes else {}
|
||||
@@ -212,18 +199,18 @@ def get_all_by_isin(isin, proxy=None, session=None):
|
||||
}
|
||||
|
||||
|
||||
def get_ticker_by_isin(isin, proxy=None, session=None):
|
||||
data = get_all_by_isin(isin, proxy, session)
|
||||
def get_ticker_by_isin(isin):
|
||||
data = get_all_by_isin(isin)
|
||||
return data.get('ticker', {}).get('symbol', '')
|
||||
|
||||
|
||||
def get_info_by_isin(isin, proxy=None, session=None):
|
||||
data = get_all_by_isin(isin, proxy, session)
|
||||
def get_info_by_isin(isin):
|
||||
data = get_all_by_isin(isin)
|
||||
return data.get('ticker', {})
|
||||
|
||||
|
||||
def get_news_by_isin(isin, proxy=None, session=None):
|
||||
data = get_all_by_isin(isin, proxy, session)
|
||||
def get_news_by_isin(isin):
|
||||
data = get_all_by_isin(isin)
|
||||
return data.get('news', {})
|
||||
|
||||
|
||||
@@ -415,17 +402,19 @@ def snake_case_2_camelCase(s):
|
||||
def _parse_user_dt(dt, exchange_tz):
|
||||
if isinstance(dt, int):
|
||||
# Should already be epoch, test with conversion:
|
||||
_datetime.datetime.fromtimestamp(dt)
|
||||
dt = _pd.Timestamp(_datetime.datetime.fromtimestamp(dt)).tz_localize("UTC").tz_convert(exchange_tz)
|
||||
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())
|
||||
if isinstance(dt, _datetime.datetime):
|
||||
if dt.tzinfo is None:
|
||||
# Assume user is referring to exchange's timezone
|
||||
dt = _pd.Timestamp(dt).tz_localize(exchange_tz)
|
||||
else:
|
||||
dt = _pd.Timestamp(dt).tz_convert(exchange_tz)
|
||||
return dt
|
||||
|
||||
|
||||
@@ -526,15 +515,18 @@ def parse_actions(data):
|
||||
splits = None
|
||||
|
||||
if "events" in data:
|
||||
if "dividends" in data["events"]:
|
||||
if "dividends" in data["events"] and len(data["events"]['dividends']) > 0:
|
||||
dividends = _pd.DataFrame(
|
||||
data=list(data["events"]["dividends"].values()))
|
||||
dividends.set_index("date", inplace=True)
|
||||
dividends.index = _pd.to_datetime(dividends.index, unit="s")
|
||||
dividends.sort_index(inplace=True)
|
||||
dividends.columns = ["Dividends"]
|
||||
if 'currency' in dividends.columns and (dividends['currency'] == '').all():
|
||||
# Currency column useless, drop it.
|
||||
dividends = dividends.drop('currency', axis=1)
|
||||
dividends = dividends.rename(columns={'amount': 'Dividends'})
|
||||
|
||||
if "capitalGains" in data["events"]:
|
||||
if "capitalGains" in data["events"] and len(data["events"]['capitalGains']) > 0:
|
||||
capital_gains = _pd.DataFrame(
|
||||
data=list(data["events"]["capitalGains"].values()))
|
||||
capital_gains.set_index("date", inplace=True)
|
||||
@@ -542,7 +534,7 @@ def parse_actions(data):
|
||||
capital_gains.sort_index(inplace=True)
|
||||
capital_gains.columns = ["Capital Gains"]
|
||||
|
||||
if "splits" in data["events"]:
|
||||
if "splits" in data["events"] and len(data["events"]['splits']) > 0:
|
||||
splits = _pd.DataFrame(
|
||||
data=list(data["events"]["splits"].values()))
|
||||
splits.set_index("date", inplace=True)
|
||||
@@ -599,15 +591,40 @@ def fix_Yahoo_returning_prepost_unrequested(quotes, interval, tradingPeriods):
|
||||
return quotes
|
||||
|
||||
|
||||
def fix_Yahoo_returning_live_separate(quotes, interval, tz_exchange, repair=False, currency=None):
|
||||
def _dts_in_same_interval(dt1, dt2, interval):
|
||||
# Check if second date dt2 in interval starting at dt1
|
||||
|
||||
if interval == '1d':
|
||||
last_rows_same_interval = dt1.date() == dt2.date()
|
||||
elif interval == "1wk":
|
||||
last_rows_same_interval = (dt2 - dt1).days < 7
|
||||
elif interval == "1mo":
|
||||
last_rows_same_interval = dt1.month == dt2.month
|
||||
elif interval == "3mo":
|
||||
shift = (dt1.month % 3) - 1
|
||||
q1 = (dt1.month - shift - 1) // 3 + 1
|
||||
q2 = (dt2.month - shift - 1) // 3 + 1
|
||||
year_diff = dt2.year - dt1.year
|
||||
quarter_diff = q2 - q1 + 4*year_diff
|
||||
last_rows_same_interval = quarter_diff == 0
|
||||
else:
|
||||
last_rows_same_interval = (dt2 - dt1) < _pd.Timedelta(interval)
|
||||
return last_rows_same_interval
|
||||
|
||||
|
||||
def fix_Yahoo_returning_live_separate(quotes, interval, tz_exchange, prepost, repair=False, currency=None):
|
||||
# Yahoo bug fix. If market is open today then Yahoo normally returns
|
||||
# todays data as a separate row from rest-of week/month interval in above row.
|
||||
# Seems to depend on what exchange e.g. crypto OK.
|
||||
# Fix = merge them together
|
||||
n = quotes.shape[0]
|
||||
if n > 1:
|
||||
dt1 = quotes.index[n - 1]
|
||||
dt2 = quotes.index[n - 2]
|
||||
|
||||
if interval[-1] not in ['m', 'h']:
|
||||
prepost = False
|
||||
|
||||
dropped_row = None
|
||||
if len(quotes) > 1:
|
||||
dt1 = quotes.index[-1]
|
||||
dt2 = quotes.index[-2]
|
||||
if quotes.index.tz is None:
|
||||
dt1 = dt1.tz_localize("UTC")
|
||||
dt2 = dt2.tz_localize("UTC")
|
||||
@@ -618,25 +635,23 @@ def fix_Yahoo_returning_live_separate(quotes, interval, tz_exchange, repair=Fals
|
||||
# - exception is volume, *slightly* greater on final row (and matches website)
|
||||
if dt1.date() == dt2.date():
|
||||
# Last two rows are on same day. Drop second-to-last row
|
||||
dropped_row = quotes.iloc[-2]
|
||||
quotes = _pd.concat([quotes.iloc[:-2], quotes.iloc[-1:]])
|
||||
else:
|
||||
if interval == "1wk":
|
||||
last_rows_same_interval = dt1.year == dt2.year and dt1.week == dt2.week
|
||||
elif interval == "1mo":
|
||||
last_rows_same_interval = dt1.month == dt2.month
|
||||
elif interval == "3mo":
|
||||
last_rows_same_interval = dt1.year == dt2.year and dt1.quarter == dt2.quarter
|
||||
else:
|
||||
last_rows_same_interval = (dt1 - dt2) < _pd.Timedelta(interval)
|
||||
|
||||
if last_rows_same_interval:
|
||||
if _dts_in_same_interval(dt2, dt1, interval):
|
||||
# Last two rows are within same interval
|
||||
idx1 = quotes.index[n - 1]
|
||||
idx2 = quotes.index[n - 2]
|
||||
idx1 = quotes.index[-1]
|
||||
idx2 = quotes.index[-2]
|
||||
if idx1 == idx2:
|
||||
# Yahoo returning last interval duplicated, which means
|
||||
# Yahoo is not returning live data (phew!)
|
||||
return quotes
|
||||
return quotes, None
|
||||
|
||||
if prepost:
|
||||
# Possibly dt1 is just start of post-market
|
||||
if dt1.second == 0:
|
||||
# assume post-market interval
|
||||
return quotes, None
|
||||
|
||||
ss = quotes['Stock Splits'].iloc[-2:].replace(0,1).prod()
|
||||
if repair:
|
||||
@@ -659,31 +674,30 @@ def fix_Yahoo_returning_live_separate(quotes, interval, tz_exchange, repair=Fals
|
||||
for c in const._PRICE_COLNAMES_:
|
||||
quotes.loc[idx2, c] *= 0.01
|
||||
|
||||
# quotes.loc[idx2, 'Stock Splits'] = 2 # wtf? why doing this?
|
||||
|
||||
if _np.isnan(quotes.loc[idx2, "Open"]):
|
||||
quotes.loc[idx2, "Open"] = quotes["Open"].iloc[n - 1]
|
||||
quotes.loc[idx2, "Open"] = quotes["Open"].iloc[-1]
|
||||
# Note: nanmax() & nanmin() ignores NaNs, but still need to check not all are NaN to avoid warnings
|
||||
if not _np.isnan(quotes["High"].iloc[n - 1]):
|
||||
quotes.loc[idx2, "High"] = _np.nanmax([quotes["High"].iloc[n - 1], quotes["High"].iloc[n - 2]])
|
||||
if not _np.isnan(quotes["High"].iloc[-1]):
|
||||
quotes.loc[idx2, "High"] = _np.nanmax([quotes["High"].iloc[-1], quotes["High"].iloc[-2]])
|
||||
if "Adj High" in quotes.columns:
|
||||
quotes.loc[idx2, "Adj High"] = _np.nanmax([quotes["Adj High"].iloc[n - 1], quotes["Adj High"].iloc[n - 2]])
|
||||
quotes.loc[idx2, "Adj High"] = _np.nanmax([quotes["Adj High"].iloc[-1], quotes["Adj High"].iloc[-2]])
|
||||
|
||||
if not _np.isnan(quotes["Low"].iloc[n - 1]):
|
||||
quotes.loc[idx2, "Low"] = _np.nanmin([quotes["Low"].iloc[n - 1], quotes["Low"].iloc[n - 2]])
|
||||
if not _np.isnan(quotes["Low"].iloc[-1]):
|
||||
quotes.loc[idx2, "Low"] = _np.nanmin([quotes["Low"].iloc[-1], quotes["Low"].iloc[-2]])
|
||||
if "Adj Low" in quotes.columns:
|
||||
quotes.loc[idx2, "Adj Low"] = _np.nanmin([quotes["Adj Low"].iloc[n - 1], quotes["Adj Low"].iloc[n - 2]])
|
||||
quotes.loc[idx2, "Adj Low"] = _np.nanmin([quotes["Adj Low"].iloc[-1], quotes["Adj Low"].iloc[-2]])
|
||||
|
||||
quotes.loc[idx2, "Close"] = quotes["Close"].iloc[n - 1]
|
||||
quotes.loc[idx2, "Close"] = quotes["Close"].iloc[-1]
|
||||
if "Adj Close" in quotes.columns:
|
||||
quotes.loc[idx2, "Adj Close"] = quotes["Adj Close"].iloc[n - 1]
|
||||
quotes.loc[idx2, "Volume"] += quotes["Volume"].iloc[n - 1]
|
||||
quotes.loc[idx2, "Dividends"] += quotes["Dividends"].iloc[n - 1]
|
||||
quotes.loc[idx2, "Adj Close"] = quotes["Adj Close"].iloc[-1]
|
||||
quotes.loc[idx2, "Volume"] += quotes["Volume"].iloc[-1]
|
||||
quotes.loc[idx2, "Dividends"] += quotes["Dividends"].iloc[-1]
|
||||
if ss != 1.0:
|
||||
quotes.loc[idx2, "Stock Splits"] = ss
|
||||
quotes = quotes.drop(quotes.index[n - 1])
|
||||
dropped_row = quotes.iloc[-1]
|
||||
quotes = quotes.drop(quotes.index[-1])
|
||||
|
||||
return quotes
|
||||
return quotes, dropped_row
|
||||
|
||||
|
||||
def safe_merge_dfs(df_main, df_sub, interval):
|
||||
|
||||
@@ -1 +1 @@
|
||||
version = "0.2.52"
|
||||
version = "0.2.65"
|
||||
|
||||