本文是 Python 系列的第十篇
看
Py
Echarts
名字就猜得到
Py
Echarts
=
Python
+
Echarts
Echarts
是一个由百度开源的数据可视化工具,凭借着良好的交互性,精巧的图表设计,得到了众多开发者的认可,而
Python
就不用多说了。
当
Python
遇到了
Echarts
,就变成了
Py
Echarts
。
本帖需要的其他库如下:
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as patches
%matplotlib inline
from datetime import datetime
Matplotlib 需要的画图颜色设置如下,这也是 PyEcharts 默认的调色。
r_hex = '#dc2624' # red, RGB = 220,38,36
dt_hex = '#2b4750' # dark teal, RGB = 43,71,80
tl_hex = '#45a0a2' # teal, RGB = 69,160,162
r1_hex = '#e87a59' # red, RGB = 232,122,89
tl1_hex = '#7dcaa9' # teal, RGB = 125,202,169
g_hex = '#649E7D' # green, RGB = 100,158,125
o_hex = '#dc8018' # orange, RGB = 220,128,24
tn_hex = '#C89F91' # tan, RGB = 200,159,145
g50_hex = '#6c6d6c' # grey-50, RGB = 108,109,108
bg_hex = '#4f6268' # blue grey, RGB = 79,98,104
g25_hex = '#c7cccf' # grey-25, RGB = 199,204,207
画图有了 Matplotlib 和 Seaborn 为什么还要学 PyEcharts,看完下面它们的对比图就知道了。
下面两图画出 USDCNY 从 2016-01-01 到 2019-05-13 的 K 线图。
K 线又称蜡烛图,阴阳线。原来是日本米商用于记录米市中的行情波动的,后因其表示价格趋势的方法直观,真实,逐渐成为使用最广泛的技术图形。图像如下:
颜色不是最重要的,看 A 股的 K 线记住是「红涨绿跌」,看美股的 K 线记住是「绿涨红跌」。
重要的是 K 线是由很多「蜡烛」状的单元责成,每个单位包含四个数据:即
开盘价
、
最高价
、
最低价
、
收盘价
。所有的 K 线都是围绕这四个数据展开,反映大势的状况和价格信息。
先看用 Matplotlib 画的 K 线图,密密麻麻啥都看不清楚,根本区分不了
开盘价
、
最高价
、
最低价
、
收盘价
。
再看用 PyEcharts 画的 K 线图 (gif),也是密密麻麻的,但是注意到下方可伸缩的时间轴没?通过滑动鼠标我们可以锁定想看到的数据,比如那根大蓝柱 (
数据来源是 yahoofinancial,但我查了查在 2016-12-07,USDCNY 日内最高价没有到过 7.49,估计数据源有错
)。
除了操作滑动轴以外,上图 (左上方图例) 还可以任意显示或隐藏 K 线 (K-Line), 最高价 (high) 和最低价 (low)。
这种交互式 (interactive) 操作在我看来给图标增加了额外的维度,再反观 Matplotlib 绘制出来的 K 线图 (包含长时间历史数据图) 就像死水一潭。
你更喜欢哪个?选 Matplotlib 的可以轻轻点右上角,选 PyEcharts 的一起继续前行。
注:在公众号对话框输入 data 可下载数据和所有美如画的动态图。
本文思路也很简单,第一章来 PK 两者,PyEcharts 很自然地把 Matplotlib 比下去;第二章就看看胜者 PyEcharts 如何画多图。
本帖并不是 PyEcharts 的工具书,把里面所有类型的图都讲一遍,那些官方例子都有了。本帖还是结合金融数据,介绍几个最简单的交易策略,并用 PyEcharts 画图。
首先下载计算技术指标 (technical indicator) 的包
talib
,和 PyEcharts 包
pyecharts
。
在 Anaconda 命令框里两句话搞定。
conda install -c masdeseiscaracteres ta-lib
pip install pyecharts
引入
talib
并起个别名
ta
。
本帖画图需要
pyecharts
里的几个原件:
从
pyecharts
中引用它们
from pyecharts import Line, Kline, Pie,
Grid, Overlap, Timeline,
WordCloud
本帖目录如下:
第一章 -
Matplotlib Vs PyEcharts
1.1 K 线图
1.2 移动均线图
1.3 布林带图
1.4 相对强弱指标
图
第二章 - PyEcharts 多图
2.1 网格图
2.2 时间线轮播图
总结
注:本节和 1.2, 1.3 都用以下方式来下载和处理数据。
首先用
YahooFinancials
API 来下载若干外汇和加密货币的三年半历史数据,安装该 API 用一行代码:
pip install yahoofinancials
数据的描述如下
其中
下面代码就是从 API 获取数据:
该 API 返回结果
FX_daily
和
CFX_daily
是「字典」格式,样子非常丑陋,感受一下。
数据样子虽丑,但还满齐全,画 K 线需要的开盘价 (open)、最高价 (high)、最低价 (low)、收盘价 (close) 都有。
将上面的「原始数据」转换成 DataFrame,代码如下:
第 3 行完全是为了 YahooFinancial 里面的输入格式准备的。如果 Asset 是加密货币,直接用其股票代码;如果 Asset 是汇率,一般参数写成 EURUSD 或 USDJPY
-
如果是 EURUSD,转换成 EURUSD=X
-
如果是 USDJPY,转换成 JPY=X
第 6 行定义好开盘价、收盘价、最低价和最高价的标签。
第 7 行获取出一个「字典」格式的数据。
第 8, 9 行用列表解析式 (list comprehension) 将日期和价格获取出来。
第 11 到 13 行定义一个 DataFrame
-
值为第 9 行得到的 price 列表
-
行标签为第 8 行得到的 index 列表
-
列标签为第 6 行定义好的 columns 列表
处理过后的数据格式美如画,看看 USDCNY。
curr = 'USDCNY'
data = data_converter( FX_daily, curr, 'FX' )
data.head(3).append(data.tail(3))
数据整理好后,来看看 Matplotlib 和 PyEcharts 的 PK 吧。
Matplotlib 里面没有直接画 K 线的方法,我们用里面的块 (patch) 对象,对其填充上色,空心红色代表阳线,实心深青色代表阴线,画出来的效果图如下。
实现上图的代码 (横屏看) 如下:
第 3-6 行设置了图的大小、dpi、坐标系、标题和 x 轴范围。
第 8-9 行:对每一个数据,获取出开盘价 (open)、收盘价 (close)、最高价 (high)、最低价 (low)。
第 11-14 行:如果收盘价 > 开盘价 (阳线)
-
用 add_patch 方法加一个空心红色块 (patches.Rectangle),确定红块的左下点 x-y 坐标 (i-0,2, open),宽为 0.4,高为 close 和 open 之差。此外 fill 设为
False
就是画个空心矩形。
-
用 plot 方法加两条线,横坐标都是 i,第一条线纵坐标从 low 到 open,第一条线纵坐标从 close 到 high。
第 15-17 行:如果收盘价 < 开盘价 (阴线)
-
用 add_patch 方法加一个实心深青色块 (patches.Rectangle),确定
深青
块的左下点 x-y 坐标 (i-0,2, close),宽为 0.4,高为 open 和 close 之差。此外 fill 设为
True
就是画个实心矩形。
-
用 plot 方法加
一条线
,横坐标都是 i,纵坐标从 low 到 high (为什么画一条线呢?矩形是实心的啊)
第 19-20 行设置了 x 轴刻度以及标签,并把日期标签旋转 90 度,以免标签相互重叠。
看到这图第一印象是什么?
一样对吗?三年半的数据密密麻麻画出的 K 线看不出任何 K 线应带的信息。如果能在横轴上任意拉伸就好了,这样就可以看清楚细节了。
Matplotlib 是无能为力了,PyEcharts 闪亮登场。
PyEcharts 里画 K 线用到
Kline
对象,除此之外我们添加最高价和最低价两条线
Line
对象,再用
Overlap
对象来「叠加」它们。
第 1-2 行获取日期和汇率。
第 4 行创建 K 线对象
Kline
,设置好标题 "xxx Chart" 和位置 center。
第 5-6 行在
Kline
上添加属性
第 8 行创建折线对象
Line
。
第 9-13 行在
Line
上添加两条折线,一条是最高价,一条是最低价。
第 14 行创建叠加对象
Overlap
。第 15-16 行在
Overlap
上分别添加之前的
Kline
和
Line
,这样就把所有对象整合在一起了。
第 17 行如果被运行,该动态图被生成到 USDCNY Chart.html 网页文件里;如果没被运行,该动态图将显示在 Jupyter Notebook 中。
本例用到了
pyecharts
中的三个原件:
Kline
,
Line
和
Overlap
。它们的用法都是先创建 (可以带些
必要属性
,比如标题和尺寸),再用 add 方法添加
额外属性
。将其流程通用化得到
object = Object( 必要属性 )
object.add( 额外属性 )
如果你看懂了以上内容,你可以学会了 PyEcharts。接下来的所有例子都万变不离其宗。在后三节中,我准备用 PyEcharts 画出三个最常见的交易策略要看的指标图,分别是
-
1.2 节的移动均线图 (Moving Average, MA)
-
1.3 节的布林带 (Bollinger Band, BBand)
-
1.4 节的相对强弱指标 (Relative Strength Index, RSI)
MA, BBand 和 RSI 是量化交易常用的技术指标,通常我们用
talib
包里的函数直接计算。
移动均线 (Moving Average, MA) 是将一段时间 (也叫窗口) 内资产收盘价的平均价格连成曲线,用以显示价格趋势的一种技术指标。
平均
有不同定义,最常见的是简单移动平均 (Simple Moving Average, SMA),平均值是算术平均值,有时我们也用 MA 代表 SMA。其他常见的还有
-
指数移动平均 (Exponential Moving Average, EMA)
-
加权移动平均 (Weighted Moving Average, WMA)
-
双指数移动平均 (Double Exponential Moving Average, DEMA)
-
三动态移动平均 (Triple Exponential Moving Average, TEMA)
还有一些少见的 TRIMA, KAMA 和 MAMA。公式就不写了,知道它们是一种计算均值的方法就行。
窗口
可以自行选择,常见的有 5日、10日、20日、30日、60日等。
移动
指的是窗口不停移动,
假如一年有 252 个交易日,那么第 1 个 MA60 值需要第 1 到 60 个汇率,第 2 个 MA60 值需要第 2 到 61 个汇率,第 193 个 MA60 值需要第 193 到 252 个汇率。最终只有 193 个
MA60
。同理可得到只有 223 个
MA20
。
利用均值指标,最常见的交易策略就是「
双均线策略
」。
双均线策略:
MA60 和 MA20 必有交点,若 20 天平均线「上穿越」60 天均线,则为买入点;反之为卖出点。该策略基于不同天数均线的交叉点抓住价格的强势和弱势时刻进行交易。
下面我们来看看两种类型的移动平均图:
-
不同窗口的简单移动平均 (MA)
-
相同窗口的各式移动平均 (
X
MA)
我们以
比特币
(代码 BTC-USD) 举例来绘图。
label = 'BTC-USD'
data = data_converter( CFX_daily, label, 'CFX' )
data.head(3).append(data.tail(3))
数据整理好后,来看看 Matplotlib 和 PyEcharts 的 PK 吧。
第 1 行定义函数,label 和 data 是「位置参数」,window_periods 是「可变参数」。忘了这些参数类型的可回顾〖
Python 入门篇 (下)
〗。
第 3-6 行设置了图的大小、dpi、坐标系、标题和 x 轴范围。
第 8-10 行画出收盘价的折
线
图。
第 12-14 行遍历 window_periods 里所有值,
用
talib
里的
ta.MA
函数计算不同窗口的 MA 值,再画出其折线图。
第 15 行把图例放在图的最佳位置 (loc=0)。
画出窗口为 30日、60日和 100日的简单移动平均线 (SMA) 看看。
mpl_MA( label, data, 30, 60, 100 );
只要历史数据一多就是 Matplotlib 的死穴,只能大概看得出价格走势,但却丢失很多细节。
PyEcharts 里用 n 条线
Line
对象画移动平均图,并用
Overlap
对象来「叠加」它们。PyEcharts 里的代码比 Matplotlib 里的简洁多了。
第 1-2 行获取日期和比特币价格。
第 4 行创建折线对象
Line
,起名为 line。设置好标题 "xxx Chart" 和位置 center。
第 5-6 行在
Line
上添加属性
-
图例
:'Close'
-
x 坐标轴数据
:日期
-
y 坐标轴
数据
:比特币价格
-
x 坐标轴可拉伸
:
True
-
图例位置
:右边
-
图例排序
:竖直
-
图例文字大小
:10
第 8 行创建另一个折线对象
Line
,起名叫 line2。
第 11-13 行在
line2
上添加 n 条折线,即不同窗口的移动平均线。
第 15 行创建叠加对象
Overlap
。第 16-17 行在
Overlap
上分别添加之前的「收盘价折线」
和「n 条移动平均线」
,这样就把所有对象整合在一起了。
第 18 行如果被运行,该动态图被生成到 BTCUSD Chart.html 网页文件里;如果没被运行,该动态图将显示在 Jupyter Notebook 中。
在动态图中,你可以一次性画出很多窗口下的 MA 线,在点击图例看你感兴趣的做双均值策略 (上例看的是 MA30 和 MA60)。试想这如果在 Matplotlib 里实现不是要画很多图?
比特币在 2017 年底到达最高点,差不多 20000 美元,之后一路狂泻。近期又起来了,原因是被当成像黄金一样的避险资产了。。。
我们以
以太币
(代码 ETH-USD) 举例来绘图。
label = 'ETH-USD'
data = data_converter( CFX_daily, label, 'CFX' )
data.head(3).append(data.tail(3))
数据整理好后,来看看 Matplotlib 和 PyEcharts 的 PK 吧。
将移动平均的类型由字符型转成整数型,方便
ta.MA
函数使用。
第 1 行定义函数,label 和 data 是「位置参数」,wp 是
「默认参数」而默认值为 5,
MA_type 是「可变参数」。忘了这些参数类型的可回顾〖
Python 入门篇 (下)
〗。
第 3-6 行设置了图的大小、dpi、坐标系、标题和 x 轴范围。
第 8-9 行画出收盘价的折
线
图。
第 11-14 行遍历 MA_type 里所有值,
用
talib
里的
ta.MA
函数计算窗口为 wp的不同类型 MA 值,再画出其折线图。
第 16 行把图例放在图的最佳位置 (loc=0)。
画出窗口为 100日的 8 种移动平均线看看。
mpl_XMA( label, data, 100,
'SMA','EMA','WMA','DEMA',
'TEMA','TRIMA','KAMA','MAMA' );
这效果啥也不说了,还是看 PyEcharts 的作品吧。
PyEcharts 里还是用 n 条线
Line
对象画移动平均图,并用
Overlap
对象来「叠加」它们。
第 1-2 行获取日期和以太币价格。
第 4 行创建折线对象
Line
,起名为 line。设置好标题 "xxx Chart" 和位置 center。
第 5-6 行在
Line
上添加属性
-
图例
:'Close'
-
x 坐标轴数据
:日期
-
y 坐标轴
数据
:比特币价格
-
x 坐标轴可拉伸
:
True
-
图例位置
:右边
-
图例排序
:竖直
-
图例文字大小
:10
第 8 行创建另一个折线对象
Line
,起名叫 line2。
第 9-10 行设定好窗口 100 日,和 8 种移动平均类型的字符列表。
第 12-15 行在
line2
上添加 8 条折线,即 8
种类型
的移动平均线。
第 17 行创建叠加对象
Overlap
。第 18-19 行在
Overlap
上分别添加之前的「收盘价折线」
和「8 条移动平均线」
,这样就把所有对象整合在一起了。
第 20 行如果被运行,该动态图被生成到 ETHUSD Chart.html 网页文件里;如果没被运行,该动态图将显示在 Jupyter Notebook 中。
这横轴伸缩效果,这图例显示/隐藏效果,是不是和 Matplotlib 没得比。
注:本节和 1.4, 2.1, 2.2 都使用从 csv 里读取的股票数据。
本节使用的数据描述如下:
-
5 只股票
:AAPL, JD, BABA, FB, GS
-
1 年时期
:从 2018-02-26 到 2019-02-26
data = pd.read_csv( '1Y Stock Data.csv',
parse_dates=[0],
dayfirst=True )
data.head().append(data.tail())
上小节介绍了移动均值,这小节介绍另一个技术指标 - 布林线。
布林线 (Bollinger Line) 原理是,价格总是围绕某个中轴在一定的范围内波动,这个范围
就形成了一个带状区间 (band)。
价格就在这个区间的上限和下限之间进行波动。而这条带状区间的宽窄也会随着价格波动幅度的大小而变化。
-
价格涨跌幅度加大时,带状区变宽。
-
价格涨跌幅度变小时,带状区变窄。
布林线由三条曲线组成,分别是上轨线 (upper band)、中轨线 (mid band) 和下轨线 (lower band)。上图只画出上轨线和下轨线。
根据布林线指标的交易策略如下。
观察两点:
-
价格和三轨线关系
-
上轨线和下轨线形成的带状口
一般来说,下轨对价格有支撑作用,上轨对价格有阻力作用,中轨对价格既有支撑也有阻力作用。
-
当价格穿越上轨 (冲破阻力了),买入
-
当价格穿越下轨 (冲破支撑了),卖出
-
当价格由下向上穿越中轨,买入
-
当价格由下向上穿越中轨,卖出
此外,要结合带状口的开合,如果出现极度收缩的带状口时,如果价格开始抬升,带状口重新扩张的时候,买入。
了解好布林带后,来看看 Matplotlib 和 PyEcharts 的 PK 吧。
第 1 行定义函数,code 和 data 是「位置参数」,wp 是「默认参数」而默认值为 5,MAtype 是「可变参数」。忘了这些参数类型的可回顾〖
Python 入门篇 (下)
〗。
第 3 行根据 code 获取股票信息。
第 5-8 行设置了图的大小、dpi、坐标系、标题和 x 轴范围。
第 10-23 行在 1.1 节画 K 线图解释的很清楚了。
第 27 行用
talib
里的
ta.BBANDS
函数计算上轨线、中轨线和下轨线。在本例中设定 5 日 EMA,2 倍的波动率水平。即
第 29-33 行创建第二个坐标系,把三轨线叠加到 K 线上,图例放在图的最佳位置 (loc=0)。
运行程序看看苹果股票的布林带。
mpl_BBAND( 'AAPL', data, MAtype='EMA' );
不吐槽了。。。
PyEcharts 里画 K 线用到
Kline
对象,再用
Line
对象画上轨线、中轨线和下轨线,最后
Overlap
对象来「叠加」它们。
代码很简单,用的原件
Kline
,
Line
和
Overlap
之前都解释过了,自己看问题不大。
效果好到爆有没有?
这小节介绍最后一个技术指标 - 相对强弱指标。
相对强弱指数 (Relative Strength Index, RSI) 是通过特定时期价格变动情况计算市场买卖力量对比,来判断价格内部本质强弱、推测价格未来的变动方向。
RSI 的计算公式如下 (RSI 是一个 0 到 100 的数)
根据相对强弱指标的交易策略如下。
RSI 是个趋势指标,通常来讲
-
当 RSI < 30 (超卖了),可考虑买入
-
当 RSI > 70 (超买了),可考虑卖出
来看看 Matplotlib 和 PyEcharts 的 PK 吧。
第 1 行定义函数,code 和 data 是「位置参数」,wp 是「默认参数」而默认值为 5。忘了这些参数类型的可回顾〖
Python 入门篇 (下)
〗。
第 3 行根据 code 获取股票信息。
第 5-8 行设置了图的大小、dpi、坐标系、标题和 x 轴范围。
第 10-23 行在 1.1 节画 K 线图解释的很清楚了。
第 25 行用
talib
里的
ta.RSI
函数计算 RSI 值。在本例中设定 14 日历史窗口。
第 27-31 行创建第二个坐标系,把 RSI 线、支撑线 (30)、阻力线 (70) 叠加到 K 线上,图例放在图的最佳位置 (loc=0)。
运行程序看看高盛股票的 RSI。
RSI 突破 30 -70 的点还是能看清楚的,但看完 PyEcharts 画的图再作评价。
PyEcharts 里画 K 线用到
Kline
对象,再用
Line
对象画 RSI 线、支撑线和阻力线,最后
Overlap
对象来「叠加」它们。
代码很简单,用的原件
Kline
,
Line
和
Overlap
之前都解释过了,自己看问题不大。
把 K 线去掉,看 RSI 是否突破支撑线或阻力线特别清楚。