python 工具箱
交易工具箱 (trading-toolbox)
After a several months-long hiatus, I can finally resume posting to the Trading Toolbox Series. We started this series by learning how to plot indicators (specifically: moving averages) on the top of a price chart. Moving averages belong to a wide group of indicators, called overlay indicators, that share the same scale as the price and can, therefore, be plotted on the same chart. Other technical indicators, however, do not have this advantage and we need to plot them on a separate area, sometimes called a subplot.
经过几个月的中断后,我终于可以恢复发布到“交易工具箱系列”了。 我们通过学习如何在价格图表顶部绘制指标(特别是移动平均线)来开始本系列文章。 移动平均线属于广泛的一组指标,称为叠加指标 ,它们与价格具有相同的比例,因此可以绘制在同一张图表上。 但是,其他技术指标没有这种优势,我们需要将它们绘制在一个单独的区域(有时称为子图)上 。
Here is an example of a stock chart with an indicator on a separate pane taken from Yahoo! Finance:
这是一个股票图表的示例,该图表在一个单独的窗格中带有从Yahoo!获取的指标。 财务 :
With this post, we want to explore how to create similar charts using Matplotlib. We also want to explore how to harness Matplotlib’s potential for customization and create original, publication-quality charts. To start with, we will learn how we can obtain that kind of subplot using Matplotlib. Then, we will apply that to plot our first technical indicator below the price, the Rate of Change (or ROC). We will then have a look at how to do that on an OHLC bar or Candlestick chart instead of a line chart.
在这篇文章中,我们想探讨如何使用Matplotlib创建类似的图表。 我们还想探索如何利用Matplotlib进行定制的潜力,并创建具有出版质量的原始图表。 首先,我们将学习如何使用Matplotlib获得这种子图。 然后,我们将其应用到价格, 变化率 (或ROC )下绘制我们的第一个技术指标。 然后,我们将看看如何在OHLC条形图或烛形图而不是折线图上执行此操作。
使用matplotlib的多个子图 (Multiple subplots with matplotlib)
At this stage we need to delve into some technical aspects of how Matplotlib works: That is how we can harness its multiple plots capabilities and craft publishing quality charts. All the code provided assumes that you are using Jupyter Notebook. If instead, you are using a more conventional text editor or the command line, you will need to add:
在此阶段,我们需要深入研究Matplotlib的工作原理的一些技术方面:这就是我们如何利用其多个绘图功能并制作发布质量图表的方式。 提供的所有代码均假定您正在使用Jupyter Notebook 。 相反,如果您使用的是更常规的文本编辑器或命令行,则需要添加:
plt.show()
each time a chart is created in order to make it visible.
每次创建图表以使其可见。
In the first two posts of this series we created our first financial price plots using the format:
在本系列的前两篇文章中,我们使用以下格式创建了第一个金融价格图:
plt.plot(dates, price, <additional parameters>)
You can see the first article on moving averages or the second on weighted and exponential moving averages.
您可以看到第一篇有关移动平均值的文章,或者第二篇有关加权和指数移动平均值的文章 。
When calling that method, matplotlib does a few things behind the scenes in order to create charts:
调用该方法时, matplotlib会在后台执行一些操作以创建图表:
First, it creates an object called figure: this is the container where all of our charts are stored. A figure is created automatically and quietly, however, we can create it explicitly and access it when we need to pass some parameters, e.g. with the instruction:
fig = plt.figure(figsize=(12,6))
首先,它创建一个名为Figure的对象:这是存储我们所有图表的容器。 图形是自动,安静地创建的,但是,我们可以显式创建它,并在需要传递某些参数时访问它,例如,使用以下指令:
fig = plt.figure(figsize=(12,6))
On top of that, matplotlib creates an object called axes (do not confuse with axis): this object corresponds to a single subplot contained within the figure. Again, this action usually happens behind the scenes.
最重要的是,matplotlib创建一个对象称为轴 (不要混淆轴 ):该对象对应于一个单一副区包含图之内。 同样,此动作通常在幕后发生。
Within any figure, we can have multiple subplots (axes) arranged in a matrix:
在任何图中 ,我们可以将多个子图( 轴 )排列成一个矩阵:
我们的第一个多图 (Our first multiple plot charts)
When it comes to charts with multiple subplots, there are enough ways and methods available to make our head spin. We are going to pick just one: the .subplot()
method will serve our purposes well. Through other tutorials, you may come across a method called .add_subplot()
: the .subplot()
method is a wrapper for .add_subplots()
(that means it should make its use simpler). With the exception of a few details, their use is actually very similar.
当涉及具有多个子图的图表时,有足够的方法可以使我们旋转。 我们将只选择一种: .subplot()
方法将很好地满足我们的目的。 通过其他教程,你可能会遇到一个方法叫做.add_subplot()
在.subplot()
方法是一个包装.add_subplots()
这意味着它应该使它的使用更简单)。 除了一些细节外,它们的用法实际上非常相似。
Whenever we add a subplot to a figure we need to supply three parameters:
每当我们向图形添加子图时,我们都需要提供三个参数:
- The number of rows in the chart matrix. 图表矩阵中的行数。
- The number of columns. 列数。
The number of the specific subplot: you can note from the diagram above that the axes objects are numbered going left to right, then top to bottom.
特定子图的编号:您可以从上图中注意到, 轴对象的编号从左到右,然后从上到下。
Let us try to build a practical example of a generic 2x2 multiple plot chart:
让我们尝试构建一个通用的2x2多重绘图图的实际示例:
Which gives us the following chart:
如下图所示:
在价格序列中添加指标子图 (Adding an indicator subplot to a price series)
Now that we know how to create charts with multiple plots, we can apply our skills to plot an indicator at the bottom of a price chart. For this task, we are going to use an indicator known as Rate of Change (ROC). There are actually a few different definitions of ROC, and the one that we are going to employ for our example is based on the formula:
既然我们知道如何创建包含多个图表的图表,我们就可以运用我们的技能在价格图表的底部绘制一个指标。 对于此任务,我们将使用称为变化率 ( ROC )的指标。 实际上,ROC有一些不同的定义,我们将在本示例中采用的定义基于以下公式:
where lag can be any whole number greater than zero and represents the number of periods (on a daily chart: days) we are looking back to compare our price. E.g., when we compute the ROC of the daily price with a 9-day lag, we are simply looking at how much, in percentage, the price has gone up (or down) compared to 9 days ago. In this article we are not going to discuss how to interpret the ROC chart and use it for investment decisions: that should better have a dedicated article and we are going to do that in a future post.
滞后可以是大于零的任何整数,并且代表周期数(在日线图上为天),我们正在回头比较价格。 例如,当我们以9天的滞后时间计算每日价格的ROC时,我们只是在看价格与9天前相比上涨(或下跌)了多少(以百分比表示)。 在本文中,我们将不讨论如何解释ROC图表并将其用于投资决策:最好有一篇专门的文章,我们将在以后的文章中进行介绍。
We start by preparing our environment:
我们从准备环境开始:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt# Required by pandas: registering matplotlib date converters
pd.plotting.register_matplotlib_converters()# If you are using Jupyter, use this to show the output images within the Notebook:
%matplotlib inline
For this exercise, I downloaded from Yahoo! Finance daily prices for the Invesco QQQ Trust, an ETF that tracks the performance of the Nasdaq 100 Index. You can find here the CSV file that I am using. We can load our data and have a glimpse at it:
对于本练习,我从Yahoo!下载。 跟踪纳斯达克100指数表现的ETF Invesco QQQ Trust的每日价格。 您可以在这里找到我正在使用的CSV文件 。 我们可以加载数据并浏览一下:
datafile = 'QQQ.csv'
data = pd.read_csv(datafile, index_col = 'Date')# Converting the dates from string to datetime format:
data.index = pd.to_datetime(data.index)data
Which looks like:
看起来像:
We can then compute a ROC series with a 9-day lag and add it as a column to our data frame:
然后,我们可以计算出滞后9天的ROC系列,并将其作为一列添加到我们的数据框中:
lag = 9
data['ROC'] = ( data['Adj Close'] / data['Adj Close'].shift(lag) -1 ) * 100data[['Adj Close', 'ROC']]
Which outputs:
哪个输出:
To make our example charts easier to read, we use only a selection of our available data. Here is how we select the last 100 rows, corresponding to the 100 most recent trading days:
为了使示例图表更易于阅读,我们仅使用部分可用数据。 这是我们如何选择最后100行(对应于最近100个交易日)的方式:
data_sel = data[-100:]
dates = data_sel.index
price = data_sel['Adj Close']
roc = data_sel['ROC']
We are now ready to create our first multiple plot chart, with the price at the top and the ROC indicator at the bottom. We can note that, compared to a generic chart with subplots, our indicator has the same date and time (the horizontal axis) as the price chart:
现在,我们准备创建我们的第一个多幅图,价格在顶部,ROC指标在底部。 我们可以注意到,与带有子图的普通图表相比,我们的指标具有与价格图表相同的日期和时间(水平轴):
fig = plt.figure(figsize=(12,10))# The price subplot:
price_ax = plt.subplot(2,1,1)
price_ax.plot(dates, price)# The ROC subplot shares the date axis with the price plot:
roc_ax = plt.subplot(2,1,2, sharex=price_ax)
roc_ax.plot(roc)# We can add titles to each of the subplots:
price_ax.set_title("QQQ - Adjusted Closing Price")
roc_ax.set_title("9-Day ROC")
We have just plotted our first chart with price and ROC in separate areas: this chart does its job in the sense that it makes both price and indicator visible. It does not, however, do it in a very visually appealing way. To start with, price and ROC share the same time axis: there is no need to apply the date labels again on both charts. We can remove them from the top chart by using:
我们刚刚在不同区域绘制了第一张图表,其中包含价格和ROC:此图表在使价格和指标均可见的意义上发挥了作用。 但是,它并不是以非常吸引人的方式进行的。 首先,价格和ROC共享相同的时间轴:无需在两个图表上再次应用日期标签 。 我们可以使用以下方法从顶部图表中删除它们:
price_ax.get_xaxis().set_visible(False)
We can also remove the gap between the two subplots with:
我们还可以使用以下方法消除两个子图之间的差距 :
fig.subplots_adjust(hspace=0)
It is also a good idea to add a horizontal line at the zero level of the ROC to make it more readable, as well as to add labels to both vertical axes.
在ROC的零位添加一条水平线以使其更具可读性,并且在两个垂直轴上都添加标签也是一个好主意。
fig = plt.figure(figsize=(12,10))price_ax = plt.subplot(2,1,1)
price_ax.plot(dates, price, label="Adj Closing Price")
price_ax.legend(loc="upper left")roc_ax = plt.subplot(2,1,2, sharex=price_ax)
roc_ax.plot(roc, label="9-Day ROC", color="red")
roc_ax.legend(loc="upper left")price_ax.set_title("QQQ Daily Price")# Removing the date labels and ticks from the price subplot:
price_ax.get_xaxis().set_visible(False)# Removing the gap between the plots:
fig.subplots_adjust(hspace=0)# Adding a horizontal line at the zero level in the ROC subplot:
roc_ax.axhline(0, color = (.5, .5, .5), linestyle = '--', alpha = 0.5)# We can add labels to both vertical axis:
price_ax.set_ylabel("Price ($)")
roc_ax.set_ylabel("% ROC")
This chart looks already better. However, Matplotlib offers a much greater potential when it comes to creating professional-looking charts. Here are some examples of what we can do:
该图表看起来已经更好。 但是,在创建具有专业外观的图表时,Matplotlib具有更大的潜力。 以下是一些我们可以做的例子:
To enhance the readability of the ROC indicator, we can fill the areas between the plot and the horizontal line. The
.fill_between()
method will serve this purpose.为了提高ROC指标的可读性,我们可以填充曲线图和水平线之间的区域。
.fill_between()
方法将用于此目的。We can format the date labels to show, for example, only the name of the month in short form (e.g., Jan, Feb, …).
我们可以设置日期标签的格式,以仅显示简短形式的月份名称(例如Jan , Feb …)。
- We can use a percent format for the labels on the ROC vertical axis. 我们可以对ROC垂直轴上的标签使用百分比格式。
- We can add a grid to both subplots and set a background color. 我们可以将网格添加到两个子图中并设置背景颜色。
- Increase the margins (padding) between the plot and the borders. 增加图和边框之间的边距(边距)。
In order to maximize the chart’s Data-Ink Ratio, we can remove all the spines (the borders around the subplots) and the tick marks on the horizontal and vertical axis for both subplots.
为了最大化图表的数据墨水比 ,我们可以删除两个子图的所有尖刺(子图周围的边界)和水平和垂直轴上的刻度线。
- We can also set the default size for all the fonts to a larger number, say 14. 我们还可以将所有字体的默认大小设置为更大的数字,例如14。
That is quite a long list of improvements. Without getting lost too much in the details, the following code should provide a good example:
这是一长串的改进。 不会在细节上迷失过多,以下代码应提供一个很好的示例:
Which gives:
这使:
This chart provides a taster of what we can achieve by manipulating the default Matplotlib parameters. Of course, we can always achieve some visual improvements by applying an existing style sheet as we have done in the first article of this series, e.g. with:
该图表提供了一个尝试者,可以通过操作默认的Matplotlib参数来实现。 当然,我们总是可以通过应用现有样式表来实现一些视觉上的改进,就像在本系列的第一篇文章中所做的那样,例如:
plt.style.use('fivethirtyeight')
When using indicator subplots, most of the time we want the price section to take a larger area than the indicator section in the chart. To achieve this we need to manipulate the invisible grid that Matplotlib uses to place the subplots. We can do so using the GridSpec
function. This is another very powerful feature of Matplotlib. I will just provide a brief example of how it can be used to control the height ratio between our two subplots:
当使用指标子图时,大多数时候我们希望价格部分比图表中的指标部分更大的面积。 为此,我们需要操纵Matplotlib用于放置子图的不可见网格。 我们可以使用GridSpec
函数来实现 。 这是Matplotlib的另一个非常强大的功能。 我将提供一个简短的示例,说明如何使用它来控制两个子图之间的高度比 :
Which outputs:
哪个输出:
As a side note, you may notice how this chart retained 14 as the font size set from the previous chart’s code. This happens because any changes to the rcParams
Matplotlib parameters are permanent (until we restart the system). If we need to reset them we can use:
附带说明一下,您可能会注意到此图表如何保留14作为上一个图表代码中设置的字体大小。 发生这种情况是因为对rcParams
Matplotlib参数的任何更改都是永久性的(直到重新启动系统)。 如果我们需要重置它们,我们可以使用:
plt.style.use('default')
and add %matplotlib inline
if we are using Jupyter Notebook.
如果我们使用的是Jupyter Notebook,则%matplotlib inline
添加%matplotlib inline
。
OHLC和烛台图的指标 (Indicators with OHLC and Candlestick charts)
In all of the previous examples, we charted the price as a line plot. Line plots are a good way to visualize prices when we have only one data point (in this case, the closing price) for each period of trading. Quite often, with financial price series, we want to use OHLC bar charts or Candlestick charts: those charts can show all the prices that summarize the daily trading activity (Open, High, Low, Close) instead of just Close.
在所有前面的示例中,我们将价格绘制为线图。 当我们在每个交易时段只有一个数据点(在本例中为收盘价)时,折线图是可视化价格的好方法。 通常,对于金融价格系列,我们要使用OHLC条形图或烛台图:这些图可以显示总结每日交易活动(开盘价,高价,低价,收盘价)的所有价格,而不仅仅是收盘价。
To plot OHLC bar charts and candlestick charts in Matplotlib we need to use the mplfinance library. As I mentioned in the previous post of this series, mplfinance development has gathered new momentum and things are rapidly evolving. Therefore, we will deal only cursorily on how to use it to create our charts.
要在Matplotlib中绘制OHLC条形图和烛台图,我们需要使用mplfinance库。 就像我在本系列的上 一篇 文章中提到的那样 , mplfinance的发展聚集了新的动力,并且事情正在Swift发展。 因此,我们将只粗略地讨论如何使用它来创建图表。
Mplfinance offers two methods to create subplots within charts and add an indicator:
Mplfinance提供了两种在图表内创建子图并添加指标的方法:
With the External Axes Method creating charts is more or less similar to what we have done so far. Mplfinance takes care of drawing the OHLC or candlesticks charts. We can then pass an Axes object with our indicator as a separate subplot.
使用“ 外部轴方法”创建图表与我们到目前为止所做的大致相似。 Mplfinance负责绘制OHLC或烛台图表。 然后,我们可以将带有指标的轴对象作为单独的子图传递。
The Panels Method is even easier to use than pure Matplotlib code: mplfinance takes control of all the plotting and styling operations for us. To manipulate the visual aspects of the chart we can apply existing styles or create our own style.
面板方法甚至比纯Matplotlib代码更易于使用: mplfinance为我们控制了所有绘图和样式操作。 要操纵图表的视觉效果,我们可以应用现有样式或创建自己的样式。
The External Axes Method was released less than a week ago from the time I am writing this. I am still looking forward to making use of it to find out what potential it can offer.
自撰写本文之日起,不到一周前发布了“ 外部轴方法” 。 我仍然期待着利用它来发现它可以提供什么潜力。
As a taster of what we can do using the mplfinance Panel Method, we can plot a candlestick chart with the volume in a separate pane:
作为品尝我们使用mplfinance面板方法可以做些什么的尝试,我们可以在单独的窗格中绘制烛台图和其体积:
import mplfinance as mpfmpf.plot(data_sel, type='candle', style='yahoo', title="QQQ Daily Price", volume=True)
We can add our ROC indicator in a separate subplot too:
我们也可以在单独的子图中添加ROC指标:
# We create an additional plot placing it on the third panel
roc_plot = mpf.make_addplot(roc, panel=2, ylabel='ROC')#We pass the additional plot using the addplot parameter
mpf.plot(data_sel, type='candle', style='yahoo', addplot=roc_plot, title="QQQ Daily Price", volume=True)
结论 (Conclusion)
There are several packages out there that make it possible to create financial charts using Python and pandas. In particular, plotly stands out for its capability to create good looking interactive charts. Matplotlib, on the other hand, may not produce the best charts straight out of the box (look at seaborn if you need that) however, it has a huge customization potential that makes it possible to create static charts that can stand out in a professional publication.
有几种软件包可以使用Python和pandas创建财务图表。 特别是, plotly以其创建美观的交互式图表的能力而脱颖而出。 另一方面,Matplotlib可能无法立即生成最佳图表(如果需要,请查看seaborn ),但是它具有巨大的自定义潜力,这使得创建静态图表可以在专业人士中脱颖而出。出版物。
That is why I believe it is well worth to get the grips on tweaking the properties of matplotlib. The future developments of mplfinance will make those possibilities even more appealing.
这就是为什么我认为调整一下matplotlib的属性非常值得。 mplfinance的未来发展将使这些可能性更具吸引力。
翻译自: https://towardsdatascience.com/trading-toolbox-04-subplots-f6c353278f78
python 工具箱
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389223.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!