- Notifications
You must be signed in to change notification settings - Fork656
Financial Markets Data Visualization using Matplotlib
License
matplotlib/mplfinance
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
matplotlib utilities for the visualization, and visual analysis, of financial data
pip install --upgrade mplfinance
- mplfinance requiresmatplotlib andpandas
- The New API
- Tutorials
- Basic Usage
- Customizing the Appearance of Plots
- Adding Your Own Technical Studies to Plots
- Subplots: Multiple Plots on a Single Figure
- Fill Between: Filling Plots with Color
- Price-Movement Plots (Renko, P&F, etc)
- Trends, Support, Resistance, and Trading Lines
- Coloring Individual Candlesticks (New: December 2021)
- Saving the Plot to a File
- Animation/Updating your plots in realtime
- ⇾Latest Release Info ⇽
- Older Release Info
- Some Background History About This Package
- Old API Availability
This repository,matplotlib/mplfinance
, contains a newmatplotlib finance API that makes it easier to create financial plots. It interfaces nicely withPandas DataFrames.
More importantly,the new API automatically does the extra matplotlib work that the user previously had to do "manually" with the old API. (The old API is still available within this package; see below).
The conventional way to import the new API is as follows:
importmplfinanceasmpf
The most common usage is then to call
mpf.plot(data)
wheredata
is aPandas DataFrame
object containing Open, High, Low and Close data, with a PandasDatetimeIndex
.
Details on how to call the new API can be found below underBasic Usage, as well as in the jupyter notebooks in theexamples folder.
I am very interested to hear from you regarding what you think of the newmplfinance
, plus any suggestions you may have for improvement. You can reach me atdgoldfarb.github@gmail.com or, if you prefer, provide feedback or a ask question on ourissues page.
Start with a Pandas DataFrame containing OHLC data. For example,
importpandasaspddaily=pd.read_csv('examples/data/SP500_NOV2019_Hist.csv',index_col=0,parse_dates=True)daily.index.name='Date'daily.shapedaily.head(3)daily.tail(3)
(20, 5)
Open | High | Low | Close | Volume | |
---|---|---|---|---|---|
Date | |||||
2019-11-01 | 3050.72 | 3066.95 | 3050.72 | 3066.91 | 510301237 |
2019-11-04 | 3078.96 | 3085.20 | 3074.87 | 3078.27 | 524848878 |
2019-11-05 | 3080.80 | 3083.95 | 3072.15 | 3074.62 | 585634570 |
...
Open | High | Low | Close | Volume | |
---|---|---|---|---|---|
Date | |||||
2019-11-26 | 3134.85 | 3142.69 | 3131.00 | 3140.52 | 986041660 |
2019-11-27 | 3145.49 | 3154.26 | 3143.41 | 3153.63 | 421853938 |
2019-11-29 | 3147.18 | 3150.30 | 3139.34 | 3140.98 | 286602291 |
After importing mplfinance, plotting OHLC data is as simple as callingmpf.plot()
on the dataframe
importmplfinanceasmpfmpf.plot(daily)
The default plot type, as you can see above, is'ohlc'
. Other plot types can be specified with the keyword argumenttype
, for example,type='candle'
,type='line'
,type='renko'
, ortype='pnf'
mpf.plot(daily,type='candle')
mpf.plot(daily,type='line')
year=pd.read_csv('examples/data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True)year.index.name='Date'mpf.plot(year,type='renko')
mpf.plot(year,type='pnf')
We can also plot moving averages with themav
keyword
- use a scalar for a single moving average
- use a tuple or list of integers for multiple moving averages
mpf.plot(daily,type='ohlc',mav=4)
mpf.plot(daily,type='candle',mav=(3,6,9))
We can also displayVolume
mpf.plot(daily,type='candle',mav=(3,6,9),volume=True)
Notice, in the above chart, there are no gaps along the x-coordinate, even though there are days on which there was no trading.Non-trading days are simply not shown (since there are no prices for those days).
However, sometimes people like to see these gaps, so that they can tell, with a quick glance, where the weekends and holidays fall.
Non-trading days can be displayed with the
show_nontrading
keyword.- Note that for these purposesnon-trading intervals are those thatare not represented in the data at all. (There are simply no rows for those dates or datetimes). This is because, when data is retrieved from an exchange or other market data source, that data typically willnot include rows for non-trading days (weekends and holidays for example). Thus ...
show_nontrading=True
will display all dates (all time intervals) between the first time stamp and the last time stamp in the data (regardless of whether rows exist for those dates or datetimes).show_nontrading=False
(the default value) will showonly dates (or datetimes) that have actual rows in the data. (This means that if there are rows in your DataFrame that exist but contain onlyNaN
values, these rowswill still appear on the plot even ifshow_nontrading=False
)
For example, in the chart below, you can easily see weekends, as well as a gap at Thursday, November 28th for the U.S. Thanksgiving holiday.
mpf.plot(daily,type='candle',mav=(3,6,9),volume=True,show_nontrading=True)
We can also plot intraday data:
intraday=pd.read_csv('examples/data/SP500_NOV2019_IDay.csv',index_col=0,parse_dates=True)intraday=intraday.drop('Volume',axis=1)# Volume is zero anyway for this intraday data setintraday.index.name='Date'intraday.shapeintraday.head(3)intraday.tail(3)
(1563, 4)
Open | Close | High | Low | |
---|---|---|---|---|
Date | ||||
2019-11-05 09:30:00 | 3080.80 | 3080.49 | 3081.47 | 3080.30 |
2019-11-05 09:31:00 | 3080.33 | 3079.36 | 3080.33 | 3079.15 |
2019-11-05 09:32:00 | 3079.43 | 3079.68 | 3080.46 | 3079.43 |
...
Open | Close | High | Low | |
---|---|---|---|---|
Date | ||||
2019-11-08 15:57:00 | 3090.73 | 3090.70 | 3091.02 | 3090.52 |
2019-11-08 15:58:00 | 3090.73 | 3091.04 | 3091.13 | 3090.58 |
2019-11-08 15:59:00 | 3091.16 | 3092.91 | 3092.91 | 3090.96 |
The above dataframe contains Open,High,Low,Close data at 1 minute intervals for the S&P 500 stock index for November 5, 6, 7 and 8, 2019. Let's look at the last hour of trading on November 6th, with a 7 minute and 12 minute moving average.
iday=intraday.loc['2019-11-06 15:00':'2019-11-06 16:00',:]mpf.plot(iday,type='candle',mav=(7,12))
The "time-interpretation" of themav
integers depends on the frequency of the data, because the mav integers are thenumber of data points used in the Moving Average (not the number of days or minutes, etc). Notice above that for intraday data the x-axis automatically displays TIMEinstead of date. Below we see that if the intraday data spans into two (or more) trading days the x-axis automatically displaysBOTH TIME and DATE
iday=intraday.loc['2019-11-05':'2019-11-06',:]mpf.plot(iday,type='candle')
In the plot below, we see what an intraday plot looks like when wedisplay non-trading time periods withshow_nontrading=True
for intraday data spanning into two or more days.
mpf.plot(iday,type='candle',show_nontrading=True)
Below: 4 days of intraday data withshow_nontrading=True
mpf.plot(intraday,type='ohlc',show_nontrading=True)
Below: the same 4 days of intraday data withshow_nontrading
defaulted toFalse
.
mpf.plot(intraday,type='line')
Below: Daily data spanning across a year boundary automatically adds theYEAR to the DATE format
df=pd.read_csv('examples/data/yahoofinance-SPY-20080101-20180101.csv',index_col=0,parse_dates=True)df.shapedf.head(3)df.tail(3)
(2519, 6)
Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|
Date | ||||||
2007-12-31 | 147.100006 | 147.610001 | 146.059998 | 146.210007 | 118.624741 | 108126800 |
2008-01-02 | 146.529999 | 146.990005 | 143.880005 | 144.929993 | 117.586205 | 204935600 |
2008-01-03 | 144.910004 | 145.490005 | 144.070007 | 144.860001 | 117.529449 | 125133300 |
...
Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|
Date | ||||||
2017-12-27 | 267.380005 | 267.730011 | 267.010010 | 267.320007 | 267.320007 | 57751000 |
2017-12-28 | 267.890015 | 267.920013 | 267.450012 | 267.869995 | 267.869995 | 45116100 |
2017-12-29 | 268.529999 | 268.549988 | 266.640015 | 266.859985 | 266.859985 | 96007400 |
mpf.plot(df[700:850],type='bars',volume=True,mav=(20,40))
For more examples of using mplfinance, please see the jupyter notebooks in theexamples
directory.
My name is Daniel Goldfarb. In November 2019, I became the maintainer ofmatplotlib/mpl-finance
. That module is being deprecated in favor of the currentmatplotlib/mplfinance
. The oldmpl-finance
consisted of code extracted from the deprecatedmatplotlib.finance
module along with a few examples of usage. It has been mostly un-maintained for the past three years.
It is my intention to archive thematplotlib/mpl-finance
repository soon, and direct everyone tomatplotlib/mplfinance
. The main reason for the rename is to avoid confusion with the hyphen and the underscore: As it was,mpl-finance
wasinstalled with the hyphen, but imported with an underscorempl_finance
. Going forward it will be a simple matter of both installing and importingmplfinance
.
With this newmplfinance
package installed, in addition to the new API, users can still access the old API.
The old API may be removed someday, but for the foreseeable future we will keep it ... at least until we are very confident that users of the old API can accomplish the same things with the new API.
To access the old API with the newmplfinance
package installed, change the old import statements
from:
frommpl_financeimport<method>
to:
frommplfinance.original_flavorimport<method>
where<method>
indicates the method you want to import, for example:
frommplfinance.original_flavorimportcandlestick_ohlc
About
Financial Markets Data Visualization using Matplotlib