1

Getting an error Timestamp object is not subscriptable. I understand what it means, but can't figure out how to solve the code.

import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from mplfinance.original_flavor import candlestick_ohlc

API_URL = 'https://api.coingecko.com/api/v3'

r = requests.get(API_URL + '/coins/bitcoin/market_chart?vs_currency=usd&days=3&interval=hourly')

d = r.json()

df = pd.DataFrame(d['prices'], columns = ['dateTime', 'price'])
df['date'] = pd.to_datetime(df['dateTime'], unit='ms')

ohlc = df.set_index('date')['price'].resample('1h').ohlc()

stock_data = ohlc

class CandlesIndexes():
    def __init__(self, stock_data):
        self.high = stock_data.high
        self.low = stock_data.low
        self.close = stock_data.close
        self.stock_data = stock_data
        self.date = stock_data.index

    def display_candle_bars(self):
        fig, self.ax = plt.subplots()
        #Describe candle properties
        candle_ohlc = candlestick_ohlc(self.ax, self.date, width= 0.6, colorup= 'green', colordown= 'red', alpha= 0.8)

The error happens at the very last candle_ohlc = candlestick_ohlc() line.

Please help a brotha out. Thanks, much appreciated.

EDIT: full error:

  File "/Users/teo/.local/share/virtualenvs/trend-nriNAUCq/lib/python3.8/site-packages/mplfinance/original_flavor.py", line 234, in candlestick_ohlc
    return _candlestick(ax, quotes, width=width, colorup=colorup,
  File "/Users/teo/.local/share/virtualenvs/trend-nriNAUCq/lib/python3.8/site-packages/mplfinance/original_flavor.py", line 283, in _candlestick
    t, open, high, low, close = q[:5]
TypeError: 'Timestamp' object is not subscriptable```
Daniel Goldfarb
  • 6,937
  • 5
  • 29
  • 61
Teo
  • 97
  • 1
  • 9
  • What is the error? Did you import this `from matplotlib.finance import candlestick_ohlc`? – Paulo Marques Feb 03 '21 at 21:31
  • Indeed. I added the imports above. The error is this: ```t, open, high, low, close = q[:5] TypeError: 'Timestamp' object is not subscriptable``` – Teo Feb 03 '21 at 21:35
  • The variable `self.date` should be a list. Try `[self.date]` and see the result. It might give you something but not what you expected. Take a look at [this](https://pythonprogramming.net/candlestick-ohlc-graph-matplotlib-tutorial/) – Paulo Marques Feb 03 '21 at 21:40
  • Nop, doesn't work, gives error ```TypeError: unsupported operand type(s) for -: 'Timestamp' and 'float'``` But thanks for the video, I'll check it out. – Teo Feb 03 '21 at 21:42
  • 1
    You're using ```candlestick_ohlc``` incorrectly. The second input should be the entire dataset, not just the dates. Take a look at [this](https://stackoverflow.com/questions/41821916/charting-candlestick-ohlc-one-minute-bars-with-pandas-and-matplotlib) for more info. – goalie1998 Feb 03 '21 at 21:59
  • @goalie1998 by second input, which part of the code do you mean? – Teo Feb 04 '21 at 01:11
  • Here: ```candle_ohlc = candlestick_ohlc(self.ax, self.date, width= 0.6, colorup= 'green', colordown= 'red', alpha= 0.8)``` should be ```candlestick_ohlc(self.ax, self.data.values, width= 0.6, colorup= 'green', colordown= 'red', alpha= 0.8)``` I think you also have to use your dates as a column too, not an index. ```candlestick_ohlc``` was mostly deprecated, and there isn't great documentation for it, but looking at the [code](https://github.com/matplotlib/mplfinance/blob/master/src/mplfinance/original_flavor.py), that's what it looks like to me. – goalie1998 Feb 04 '21 at 02:20
  • Yes, I need to have the dates as a column, not an index, that is the problem. But I have no idea how to solve it. I tried almost everything. ```ohlc = df.set_index('date')['price'].resample('1H').ohlc()``` converts the date column into an index, and it seems like it is not possible to have the date column alongside the OHLC... – Teo Feb 04 '21 at 02:29

2 Answers2

1

There are a few issues with your code as is.

First, it is generally a bad idea to name a variable with the same name as a method/function (ohlc).

Second, it appears you are pulling data from the server in hourly intervals, and then trying to resample the data for ohlc() in the same hourly intervals - this will give you equal values for open, high, close and low. You need to either increase your frequency for the data pulled from the API, or decrease the frequency for the resampling.

Third, you are using candlestick_ohlc() incorrectly. You need to first create a column (not an index) with the datetimes (in a format usable by candlestick_ohlc()), and then pass the values only of that data frame to the function.

This sample works as described, but can still be improved upon:

import requests
import matplotlib.pyplot as plt
from mplfinance.original_flavor import candlestick_ohlc
import matplotlib.dates as dates

API_URL = 'https://api.coingecko.com/api/v3'

r = requests.get(API_URL + '/coins/bitcoin/market_chart?vs_currency=usd&days=3&interval=hourly')

d = r.json()

df = pd.DataFrame(d['prices'], columns=['dateTime', 'price'])
df['dateTime'] = pd.to_datetime(df['dateTime'], unit='ms')

ohla = df.set_index('dateTime')['price'].resample('1d').ohlc()

stock_data = ohla.reset_index()
stock_data["dateTime"] = stock_data["dateTime"].apply(dates.date2num)

class CandlesIndexes():
    def __init__(self, stock_data):
        self.high = stock_data.high
        self.low = stock_data.low
        self.close = stock_data.close
        self.stock_data = stock_data
        self.date = stock_data.index

    def display_candle_bars(self):
        fig, self.ax = plt.subplots()
        candlestick_ohlc(self.ax, self.stock_data.values, width= 0.6, colorup= 'green', colordown= 'red', alpha= 0.8)

        plt.show()


x = CandlesIndexes(stock_data)
x.display_candle_bars()
goalie1998
  • 1,427
  • 1
  • 9
  • 16
  • However, when I try to run your code, I get the following error: ```TypeError: unsupported operand type(s) for -: 'Timestamp' and 'float'``` – Teo Feb 04 '21 at 15:51
  • UPDATE: Found out the problem - needed to use mdates.date2num as so: ```stock_data.date = stock_data.date.apply(mdates.date2num)``` – Teo Feb 04 '21 at 16:15
0

@Teo

The plotting portion of your code is far more complicated than it needs to be. Since you already have your data in a DataFrame with a Timestamp index, I recommend you use the new mplfinance module (instead of the old one that you are using). It does a lot of the work for you automatically. Thus, your code can be a lot simpler:

import requests
import pandas as pd
import mplfinance as mpf

API_URL = 'https://api.coingecko.com/api/v3'
r = requests.get(API_URL + '/coins/bitcoin/market_chart?vs_currency=usd&days=3&interval=hourly')
d = r.json()

df = pd.DataFrame(d['prices'], columns = ['dateTime', 'price'])
df['date'] = pd.to_datetime(df['dateTime'], unit='ms')

ohlcdf = df.set_index('date')['price'].resample('4h').ohlc()

mpf.plot(ohlcdf,type='candle',style='yahoo')

Result: enter image description here

Notice that I changed your resample from '1h' to '4h'. This is because your data is already approximately hourly. So if you resample at 1h then your Open, High, Low, and Close will be all equal. You can easily see the difference between various resample frequencies by changing the last two lines of the above code to:

for freq in ('1h','2h','3h','4h'):
    ohlcdf = df.set_index('date')['price'].resample(freq).ohlc()
    mpf.plot(ohlcdf,type='candle',style='yahoo')

Notice that for '1h' you get flat lines instead of candles because o,h,l,c are all approximately the same value.

HTH.

Daniel Goldfarb
  • 6,937
  • 5
  • 29
  • 61