Wassim Mlaouhia
Wassim Mlaouhia

Reputation: 21

KeyError: 'Adj Close' when using bt library with Pandas

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

Answers (3)

A O
A O

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

Fernando Ghisi
Fernando Ghisi

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

L&#234; Ho&#224;ng Vũ
L&#234; Ho&#224;ng Vũ

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

Related Questions