Reputation: 21
I'm encountering an issue when using the bt library to fetch stock data. Specifically, the code fails with a KeyError: 'Adj Close'.
Error Message
[*********************100%***********************] 1 of 1 completed
Traceback (most recent call last):
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\indexes\base.py", line 3805, in get_loc
return self._engine.get_loc(casted_key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "index.pyx", line 167, in pandas._libs.index.IndexEngine.get_loc
File "index.pyx", line 196, in pandas._libs.index.IndexEngine.get_loc
File "pandas\\_libs\\hashtable_class_helper.pxi", line 7081, in pandas._libs.hashtable.PyObjectHashTable.get_item
File "pandas\\_libs\\hashtable_class_helper.pxi", line 7089, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 'Adj Close'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\Users\PC\Desktop\DataCamp\Data_camp_Financial-Trading-in-Python\Financial_trading_with_bt\test_of_by_library.py", line 17, in <module>
bt_data = bt.get("goog, amzn, tsla", start="2020-6-1", end="2020-12-1",column_names=['Close'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\ffn\utils.py", line 32, in _memoize
cache[key] = result = func(*args, **kw)
^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\ffn\data.py", line 70, in get
data[ticker] = provider(ticker=t, field=f, mrefresh=mrefresh, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\decorator.py", line 232, in fun
return caller(func, *(extras + args), **kw)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\ffn\utils.py", line 32, in _memoize
cache[key] = result = func(*args, **kw)
^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\ffn\data.py", line 130, in yf
return tmp[field]
~~~^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\frame.py", line 4101, in __getitem__
return self._getitem_multilevel(key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\frame.py", line 4159, in _getitem_multilevel
loc = self.columns.get_loc(key)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\indexes\multi.py", line 3040, in get_loc
loc = self._get_level_indexer(key, level=0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\indexes\multi.py", line 3391, in _get_level_indexer
idx = self._get_loc_single_level_index(level_index, key)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\indexes\multi.py", line 2980, in _get_loc_single_level_index
return level_index.get_loc(key)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\PC\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.12_qbz5n2kfra8p0\LocalCache\local-packages\Python312\site-packages\pandas\core\indexes\base.py", line 3812, in get_loc
raise KeyError(key) from err
KeyError: 'Adj Close'
Here’s the minimal code causing the issue:
import bt
# Fetch data for Google, Amazon, and Tesla
bt_data = bt.get("goog, amzn, tsla", start="2020-6-1", end="2020-12-1")
print(bt_data.head())
I updated all relevant libraries to the latest versions using:
pip install --upgrade pandas bt yfinance
Printed bt_data.columns and noticed that the 'Adj Close' column is missing from the fetched data.
Verified that yfinance is installed and working correctly to fetch stock data independently.
Upvotes: 2
Views: 410
Reputation: 11
Yes, as previous user Le said, use new get_data function.
But you only need to change the parameter auto_adjust
to get the column “Adj Close”:
data = yf.download("spy", start="2025-01-01", auto_adjust=False)
Upvotes: 1
Reputation: 488
It happens with the last version of yfinance (0.2.51), released in December (see https://pypi.org/project/yfinance/#history). If you install the version 0.2.50, you can get 'Adj Close' again (make sure to restart the environment).
Upvotes: 1
Reputation: 143
I encountered the same problem with bt
when I switched from Python 3.10 to 3.13. This issue occurred after I reinstalled the library with the new pip version.
I noticed that the data from yfinance
does not include the Adj Close
field, which bt uses to get the closing price. You can see this in their MA example here.
To resolve this, I wrote a new get_data
function that uses the Close
price instead, which provides all the data bt
needs for calculations.
Below is my workaround for this problem. Hope this helps!
import bt
import numpy as np
import yfinance as yf
def get_data(symbol, start, end=None):
data = yf.download(symbol, start=start, end=end)
data = data['Close']
list_symbols = data.columns.to_list()
rename_dict = {}
for k in list_symbols:
cleaned_k = k.lower().replace('-', '').replace(' ', '')
rename_dict[k] = cleaned_k
data = data.rename(columns=rename_dict)
return data
# Use get_data instead of bt.get
data = get_data('BTC-USD', start='2023-01-01', end='2024-01-08')
# My other data processing ...
backtest = bt.Backtest(my_btc_strategy, data)
result = bt.run(backtest)
Upvotes: 1