circuit

Plot Stock Chart Using mplfinance in Python

An introductory guide to plot a candlestick chart along with volume, MACD & stochastic using mplfinance.


If you are a Python user, there’s a high chance you have worked with matplotlib before. To make it easier to work with financial data, a new matplotlib finance API called mplfinance was created (it was first released as mpl-finance but was later renamed).

In this tutorial, we are going to learn how to use mplfinance to plot the following financial chart.

A candlestick chart with moving averages, volume, MACD, and stochastic oscillator plotted using _mplfinance_.

If you want to know how to plot the above chart using plotly, check out this article too.

Let us begin!

1. Download stock price & plot candlestick chart

First thing first, let’s get ourselves some stock prices to plot. To do that, we will be using the yfinance library.

import pandas as pd

import matplotlib.pyplot as plt

import yfinance as yf

import mplfinance as mpf

# download stock price data

symbol = 'AAPL'

df = yf.download(symbol, period='6mo')

Then, we are ready to plot our first candlestick chart of the day.

# plot candlestick chart

mpf.plot(df, type='candle')

That’s all we need. We now have a simple-looking candlestick chart.

2. Add moving averages and volume

Let’s spice things up a little by adding some moving averages and volume to the chart. With mplfinance, it is as easy as this:

# Add moving averages and volume

mpf.plot(df, type='candle', mav=(5,20), volume=True)

Note that the mav argument in the plot method is only for simple moving average. To plot other types of moving average like exponential moving average, we will need to calculate and add it to the chart separately.

3. Add MACD & Stochastics as subplots

Here comes the good part. Let’s begin with MACD.

3.1 MACD

# Add MACD as subplot

def MACD(df, window_slow, window_fast, window_signal):

macd = pd.DataFrame()

macd['ema_slow'] = df['Close'].ewm(span=window_slow).mean()

macd['ema_fast'] = df['Close'].ewm(span=window_fast).mean()

macd['macd'] = macd['ema_slow'] - macd['ema_fast']

macd['signal'] = macd['macd'].ewm(span=window_signal).mean()

macd['diff'] = macd['macd'] - macd['signal']

macd['bar_positive'] = macd['diff'].map(lambda x: x if x > 0 else 0)

macd['bar_negative'] = macd['diff'].map(lambda x: x if x < 0 else 0)

return macd

macd = MACD(df, 12, 26, 9)

macd_plot = [

mpf.make_addplot((macd['macd']), color='#606060', panel=2, ylabel='MACD', secondary_y=False),

mpf.make_addplot((macd['signal']), color='#1f77b4', panel=2, secondary_y=False),

mpf.make_addplot((macd['bar_positive']), type='bar', color='#4dc790', panel=2),

mpf.make_addplot((macd['bar_negative']), type='bar', color='#fd6b6c', panel=2),

]

mpf.plot(df, type='candle', volume=True, addplot=macd_plot)
  • Line 2–11:
    A function that calculates and returns the MACD.
  • Line 13:
    Call the MACD function with periods of 12, 26, and 9.
  • Line 14–19:
    We are utilizing the make_addplot function to construct a list of plots we want to add to the main chart:
    1. MACD line
    2. Signal line
    3. Histogram (green bar)
    4. Histogram (red bar)
  • Line 21:
    Add MACD plots to the main chart

Running the code above gives us the following chart:

3.2 Stochastic Oscillator

Let’s proceed with the stochastic oscillator.

# Stochastic

def Stochastic(df, window, smooth_window):

stochastic = pd.DataFrame()

stochastic['%K'] = ((df['Close'] - df['Low'].rolling(window).min()) \

/ (df['High'].rolling(window).max() - df['Low'].rolling(window).min())) * 100

stochastic['%D'] = stochastic['%K'].rolling(smooth_window).mean()

stochastic['%SD'] = stochastic['%D'].rolling(smooth_window).mean()

stochastic['UL'] = 80

stochastic['DL'] = 20

return stochastic

stochastic = Stochastic(df, 14, 3)

stochastic_plot = [

mpf.make_addplot((stochastic[['%K', '%D', '%SD', 'UL', 'DL']]), ylim=[0, 100], panel=2, ylabel='Stoch')

]

mpf.plot(df, type='candle', volume=True, addplot=stochastic_plot)
  • Line 2–10:
    A function that calculates and returns the stochastic values.
  • Line 12:
    Call the Stochastic function with window=14 and smoothing_window=3.
  • Line 13–15:
    Again, we are utilizing the make_addplot function to construct the plot we want to add to the main chart
  • Line 17:
    Add the Stochastic plot to the main chart

And we get:

4. Customization

Before we put everything together, let’s explore some of the customizations we can perform in mplfinance.

4.1 Styles

As you have realized, so far, we have been using the default mplfinance style and it looks kinda dull. mplfinance does provide some preset styles and here are some examples:

To get all the available styles:

from mplfinance import _styles
_styles.available_styles()
# ['binance',  'blueskies',  'brasil',  'charles',  'checkers',  'classic',  'default',  'ibd',  'kenan',  'mike',  'nightclouds',  'sas',  'starsandstripes',  'yahoo']

4.2 Figure size

There is a very convenient way to change the figure size in mplfinance using figscale:

mpf.plot(df, type='candle', **figscale**=1.5)

4.3 Subplot size ratio

When dealing with multiple subplots, oftentimes we want to adjust the ratio between different subplots. To do that in mplfinance, we simply use the panel_ratios option:

mpf.plot(df, type='candle', volume=True, addplot=macd_plot,
panel_ratios=(4,1,3))

Left: default ratio. Right: 4:1:3

To see more examples of customization, you can check out the official examples here.

5. Putting everything together

Putting everything together, we can use the following codes to create the plot we saw earlier:

macd = MACD(df, 12, 26, 9)

stochastic = Stochastic(df, 14, 3)

plots = [

mpf.make_addplot((macd['macd']), color='#606060', panel=2, ylabel='MACD (12,26,9)', secondary_y=False),

mpf.make_addplot((macd['signal']), color='#1f77b4', panel=2, secondary_y=False),

mpf.make_addplot((macd['bar_positive']), type='bar', color='#4dc790', panel=2),

mpf.make_addplot((macd['bar_negative']), type='bar', color='#fd6b6c', panel=2),

mpf.make_addplot((stochastic[['%D', '%SD', 'UL', 'DL']]), ylim=[0, 100], panel=3, ylabel='Stoch (14,3)')

]

mpf.plot(df, type='candle', style='yahoo', mav=(5,20), volume=True, addplot=plots, panel_ratios=(3,1,3,3), figscale=1.5)

The full code and demo notebook of this tutorial is available here.

Buy the author a coffee.




Continue Learning