1

I have a python dataframe df containing Date, Open, High,Low, Close, and volume values.

I am attempting to Candlestick chart a stock. For some reason, I can't seem to get matplotlib.finance.candlestick2_ochl() to corectly display days where the stock price closed self.df['closep'] was higher than stock price open self.df['openp']. On these positive (green) days, matplotlib either displays a doji or nothing at all.

Not quite sure why I am getting this behavior. I suspect it has something to do with the way my program is accessing the stock data from my Pandas DataFrame self.df.

Here is my code:

# Visualize my stock data

import pandas as pd
import datetime
import time
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ochl
import matplotlib.ticker as mticker
import matplotlib.dates as mdates


class MyStock:
    def __init__(self, stock):
        self.stock = stock
        self.pullData()


    def pullData(self):
        try:
            print('Currently pulling', self.stock)
            print(str(datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')))
            urlToVisit = 'http://chartapi.finance.yahoo.com/instrument/1.0/' + self.stock + '/chartdata;type=quote;range=5d/csv'

            self.df = pd.read_csv(urlToVisit, header=None, names=['date', 'closep', 'highp', 'lowp', 'openp', 'volume'],
                             skiprows=22, dtype=float)

            print('Pulled', self.stock, '\n')

        except Exception as e:
            print('main loop', str(e))

        print('Constucting DataFrame\n')
        self.df['date'] = pd.to_datetime(self.df['date'], unit='s')

        self.df = self.df.set_index('date').tz_localize('UTC').tz_convert('US/Eastern').reset_index()
        self.df['date'] = self.df['date'].dt.strftime('%Y-%m-%d %H:%M:%S')

        print(self.df.tail())


    def CandleStick(self):


        self.fig = plt.figure()

        ax1 = plt.subplot2grid((6, 4), (1, 0), rowspan=4, colspan=4, axisbg='w')

        candlestick2_ochl(ax1, opens=self.df['openp'], closes=self.df['closep'], highs=self.df['highp'], lows=self.df['lowp'], width=.75, colorup='k', colordown='r', alpha=0.75)

        plt.ylabel('Stock Price')
        ax1.grid(True)
        for label in ax1.xaxis.get_ticklabels():
            label.set_rotation(90)

        plt.subplots_adjust(left=.10, bottom=.19, right=.93, top=.95, wspace=.20, hspace=0)

        plt.suptitle(self.stock + ' Stock Price')
        plt.show()


amd = MyStock('AMD')
amd.CandleStick()

and a screenshot of the output alongside the associated section of the DataFrame:

enter image description here

You can clearly see in this screen cap that positive days (green) are not being displayed correctly. I am sure I'm missing something very obvious here.

Any help is appreciated.

Jack
  • 242
  • 4
  • 18

2 Answers2

2

Please see this code that produces rightly colored candlesticks:

import pandas as pd
import datetime
import time
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.finance import candlestick2_ochl
import matplotlib.ticker as mticker
import matplotlib.dates as mdates


class MyStock:
    def __init__(self, stock):
        self.stock = stock
        self.pullData()


    def pullData(self):
        try:
            print('Currently pulling', self.stock)
            print(str(datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')))
            urlToVisit = 'http://chartapi.finance.yahoo.com/instrument/1.0/' + self.stock + '/chartdata;type=quote;range=2d/csv'

            self.df = pd.read_csv(urlToVisit, header=None, names=['date', 'closep', 'highp', 'lowp', 'openp', 'volume'],
                             skiprows=22, dtype=float)

            print('Pulled', self.stock, '\n')

        except Exception as e:
            print('main loop', str(e))

        print('Constucting DataFrame\n')
        self.df['date'] = pd.to_datetime(self.df['date'], unit='s')

        self.df = self.df.set_index('date').tz_localize('UTC').tz_convert('US/Eastern').reset_index()
        self.df['date'] = self.df['date'].dt.strftime('%Y-%m-%d %H:%M:%S')

        print(self.df.tail())


    def CandleStick(self):


        self.fig = plt.figure()
        ax1 = plt.subplot2grid((6, 4), (1, 0), rowspan=4, colspan=4, axisbg='w')
        candlestick2_ochl(ax1,
                          self.df['openp'], self.df['highp'], self.df['lowp'], self.df['closep'],
                          width=.75, colorup='g', colordown='r', alpha=0.75)

        plt.ylabel('Stock Price')
        ax1.grid(True)
        for label in ax1.xaxis.get_ticklabels():
            label.set_rotation(90)

        plt.subplots_adjust(left=.10, bottom=.19, right=.93, top=.95, wspace=.20, hspace=0)

        plt.suptitle(self.stock + ' Stock Price')
        plt.show()

amd = MyStock('AMD')
amd.CandleStick()

enter image description here

Sergey Bushmanov
  • 23,310
  • 7
  • 53
  • 72
-3

a bug lies here

I'm using Matplotlib 1.5.1, there's a finance.py file in matplotlib directory, line 1059-1067. the original code is:

    candlestick2_ohlc(ax, opens, highs, closes, lows, width=width,
                 colorup=colorup, colordown=colordown,
                 alpha=alpha)


def candlestick2_ohlc(ax, opens, highs, lows, closes, width=4,
             colorup='k', colordown='r',
             alpha=0.75,
             ): 

should be :

(exchange the places of 'closes' and 'lows' in parameters)

    candlestick2_ohlc(ax, opens, highs, lows, closes, width=width,
                 colorup=colorup, colordown=colordown,
                 alpha=alpha)


def candlestick2_ohlc(ax, opens, highs, lows, closes, width=4,
             colorup='k', colordown='r',
             alpha=0.75,
             ):

edit this file and save it. it should fix your problem.

Candlestick Chart. sorry for no picture displayed here. you have to click the url above to see the effect.

solved this problem within 2 hours (it's 2 a.m. now) just the same way I guessed below 2 hours ago(but not excactly the same place), so sad that people voted me down.


Something I wroted 2 hours ago.

I found this sentence in official Matplotlib API document, Chapter:"matplotlib.finance":

Preserves the original argument order.

Does this have anything to do with your problem?

actually,i have got the same problem as you.

fig = plt.figure()
ax1 = plt.subplot(1,1,1)

candlestick(ax1,
        opens=test_data.open,
        closes=test_data.close,
        highs=test_data.high,
        lows=test_data.low,
        width=1,
        colorup='k',
        colordown='r',
        alpha=0.75)

fig.savefig('index.png',dpi=300,bbox_inches='tight')

and i got this: some wrong chart ploted by me

Léon Xu
  • 1
  • 1
  • [link](https://github.com/matplotlib/matplotlib/pull/6869) this bug and it's fix has been officially accepted by Matplotlib. – Léon Xu Aug 03 '16 at 09:43