Python 金融交易实用指南(二)(4)https://developer.aliyun.com/article/1523759
创建 DataFrame 列的条形图
可以使用 kind='bar'
参数与 pandas.DataFrame.plot(...)
方法构建条形图。
让我们首先按 'Cat value'
值对 DataFrame 进行分组,然后绘制 Delta1 discrete
值的条形图:
df.groupby('Cat value')['Delta1 discrete']\ .value_counts().plot(kind='bar', color='darkgray', title='Occurrence by (Cat,Delta1)', figsize=(12, 6))
这生成了以下图表,显示了 (Cat value,Delta1 discrete)
值对的频率:
图 5.13 – 显示(Cat value,Delta1 discrete)值对频率的垂直条形图
kind='barh'
参数创建了一个水平条形图而不是垂直条形图:
df.groupby('Delta2 discrete')['Cat value'].value_counts()\ .plot(kind='barh', color='darkgray', title='Occurrence by (Delta2,Cat)', figsize=(12, 12))
输出如下:
图 5.14 – 水平条形图显示(Delta2 离散,Cat 值)对的频率
条形图最适合比较分类值的大小。
创建 DataFrame 列的直方图和密度图
pandas.DataFrame.plot(…)
方法中的 kind='hist'
参数创建了一个直方图。
让我们创建一个 Delta1 离散
值的直方图:
df['Delta1 discrete'].plot(kind='hist', color='darkgray', figsize=(12, 6), label='Delta1') plt.legend()
生成的直方图如下所示:
图 5.15 – Delta1 离散频率的直方图
我们可以使用 kind='kde'
参数,根据 Delta2 离散
值生成一个概率密度函数(PDF):
df['Delta2 discrete'].plot(kind='kde', color='black', figsize=(12, 6), label='Delta2 kde') plt.legend()
输出如下:
图 5.16 – 显示 Delta2 离散值的概率密度函数(PDF)的 KDE 图
直方图和概率密度函数(PDF)/核密度估计(KDE)用于评估一些随机变量的概率分布。
创建两个 DataFrame 列的散点图
pandas.DataFrame.plot(...)
方法生成的散点图使用 kind='scatter'
参数。
以下代码块绘制了 Delta1
和 Delta2
值之间的散点图:
df.plot(kind='scatter', x='Delta1 value', y='Delta2 value', alpha=0.5, color='black', figsize=(8, 8))
输出如下:
图 5.17 – Delta1 值和 Delta2 值字段的散点图
pandas.plotting.scatter_matrix(...)
方法在矩阵的非对角线条目上构建散点图矩阵,并在矩阵的对角线条目上构建直方图/核密度估计(KDE)图,这些图显示了 Delta1
和 Delta2
值之间的关系:
pd.plotting.scatter_matrix(df[['Delta1 value', 'Delta2 value']], diagonal='kde', color='black', figsize=(8, 8))
输出如下:
图 5.18 – Delta1 值和 Delta2 值字段的散点矩阵图
散点图/散点矩阵用于观察两个变量之间的关系。
绘制时间序列数据
以下代码块创建了一个包含两个虚构交易工具 A
和 B
的价格的 pandas
DataFrame。 DataFrame 由表示从 1992
年到 2012
年的每日日期的 DateTimeIndex
对象索引:
dates = pd.date_range('1992-01-01', '2012-10-22') time_series = pd.DataFrame(index=dates, columns=['A', 'B']) time_series['A'] = \ np.random.randint(low=-100, high=101, size=len(dates)).cumsum() + 5000 time_series['B'] = \ np.random.randint(low=-75, high=76, size=len(dates)).cumsum() + 5000 time_series
结果 DataFrame 如下:
A B 1992-01-01 5079 5042 1992-01-02 5088 5047 ... ... ... 2012-10-21 6585 7209 2012-10-22 6634 7247 7601 rows × 2 columns
让我们使用这个时间序列代表性类型的图。
绘制线性图中的价格
首先,让我们用线性图绘制 A
和 B
的每日价格 20 年:
time_series['A'].plot(kind='line', linestyle='—', color='black', figsize=(12, 6), label='A') time_series['B'].plot(kind='line', linestyle='-.', color='darkgray', figsize=(12, 6), label='B') plt.legend()
输出如下:
图 5.19 – 20 年期间虚构仪器 A 和 B 的价格显示图
大多数时间序列图表都是线性图,而其他图表类型提供了额外的见解。
绘制价格变化直方图
金融时间序列分析中通常的下一步是检查某段时间内的价格变化。
下面的代码块使用pandas.DataFrame.shift(...)
和pandas.DataFrame.fillna(...)
方法生成表示 1 天、5 天和 20 天内价格变化的六个新字段。由于移位而导致数据缺失,我们还删除了具有缺失数据的行,并将最终的 DataFrame 保存在 time_series_delta
DataFrame 中:
time_series['A_1_delta'] = \ time_series['A'].shift(-1) – time_series['A'].fillna(0) time_series['B_1_delta'] = \ time_series['B'].shift(-1) – time_series['B'].fillna(0) time_series['A_5_delta'] = \ time_series['A'].shift(-5) – time_series['A'].fillna(0) time_series['B_5_delta'] = \ time_series['B'].shift(-5) – time_series['B'].fillna(0) time_series['A_20_delta'] = \ time_series['A'].shift(-20) – time_series['A'].fillna(0) time_series['B_20_delta'] = \ time_series['B'].shift(-20) – time_series['B'].fillna(0) time_series_deltas = time_series[['A_1_delta', 'B_1_delta', 'A_5_delta', 'B_5_delta', 'A_20_delta', 'B_20_delta']].dropna() time_series_deltas
DataFrame 包含以下内容:
A_1_delta B_1_delta A_5_delta B_5_delta A_20_delta B_20_delta 1992-01-01 9.0 5.0 -49.0 118.0 -249.0 -56.0 1992-01-02 -91.0 69.0 -84.0 123.0 -296.0 -92.0 ... ... ... ... ... ... ... 2012-10-01 88.0 41.0 -40.0 -126.0 -148.0 -84.0 2012-10-02 -10.0 -44.0 -71.0 -172.0 -187.0 -87.0 7581 rows × 6 columns
我们可以使用下面的代码块根据本章所学绘制A
的价格变化直方图:
time_series_delt's['A_20_de'ta'].plot(ki'd='h'st', col'r='bl'ck', alpha=0.5, lab'l='A_20_de'ta', figsize=(8,8)) time_series_delt's['A_5_de'ta'].plot(ki'd='h'st', col'r='darkg'ay', alpha=0.5, lab'l='A_5_de'ta', figsize=(8,8)) time_series_delt's['A_1_de'ta'].plot(ki'd='h'st', col'r='lightg'ay', alpha=0.5, lab'l='A_1_de'ta', figsize=(8,8)) plt.legend()
输出如下:
图 5.20 – A_1、A_5 和 A_20 三个值的直方图
直方图用于评估底层数据的概率分布。这个特定的直方图表明,A_20
delta 具有最大的变异性,这是合理的,因为底层数据呈现出强烈的趋势。
创建价格变化密度图
我们还可以使用 KDE PDF 绘制价格变化的密度。
下面的代码块绘制了B
的价格变化密度函数:
time_series_deltas['B_20_delta'].plot(kind='kde', linestyle='-', linewidth=2, color='black', label='B_20_delta', figsize=(8,8)) time_series_deltas['B_5_delta'].plot(kind='kde', linestyle=':', linewidth=2, color='black', label='B_5_delta', figsize=(8,8)) time_series_deltas['B_1_delta'].plot(kind='kde', linestyle='--', linewidth=2, color='black', label='B_1_delta', figsize=(8,8)) plt.legend()
输出如下:
图 5.21 – B 在 1、5 和 20 天内价格变化的 KDE 密度图
KDE 密度图与直方图非常相似。与由离散箱子组成的直方图不同,KDE 是连续的线条。
创建区间的箱线图
我们可以按年度、季度、月度或周度等不同间隔分组每日价格,并使用箱线图显示这些价格的分布。
下面的代码首先使用pandas.Grouper
对象指定年度周期性,然后将结果应用于pandas.DataFrame.groupby(…)
方法以构建pandas.DataFrameGroupBy
对象。最后,我们调用pandas.DataFrameGroupBy.boxplot(...)
方法生成箱线图。我们指定rot=90
参数以将 x 轴刻度标签旋转,使其更易读:
group_A = time_series[['A']].groupby(pd.Grouper(freq='A')) group_A.boxplot(color='black', subplots=False, rot=90, figsize=(12,12))
输出如下:
图 5.22 – 按年份分组的 A 的价格箱线图分布的图表
带有须的箱线图用于通过相应的四分位数可视化数值数据组:
- 箱子的下界对应于下四分位数,而箱子的上界表示组的上四分位数。
- 箱子内的线显示间隔的中值。
- 箱子下方的线结束于最低观测值。
- 箱子上方的线结束于最高观测值。
创建滞后散点图
我们可以使用pandas.plotting.scatter_matrix(…)
方法可视化不同价格变化变量之间的关系:
pd.plotting.scatter_matrix(time_series[['A_1_delta', 'A_5_delta', 'A_20_delta', 'B_1_delta', 'B_5_delta', 'B_20_delta']], diagonal='kde', color='black', alpha=0.25, figsize=(12, 12))
结果显示(A_5_Delta 和 A_1_Delta)
、(A_5_Delta 和 A_20_Delta)
、(B_1_Delta 和 B_5_Delta)
以及(B_5_Delta 和 B_20_Delta)
变量对之间存在一些线性关系:
图 5.23 – A 和 B 价格变量的散点矩阵图
我们还可以使用pandas.plotting.lag_plot(...)
方法,并使用不同的lag=
值来指定不同水平的滞后,以生成A
的价格与滞后价格之间的散点图:
fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(12, 12)) pd.plotting.lag_plot(time_series['A'], ax=ax1, lag=1, c='black', alpha=0.2) pd.plotting.lag_plot(time_series['A'], ax=ax2, lag=7, c='black', alpha=0.2) pd.plotting.lag_plot(time_series['A'], ax=ax3, lag=20, c='black', alpha=0.2)
这生成了滞后值为 1、7 和 20 天的三个图:
图 5.24 – A 的价格滞后 1、7 和 20 天的滞后图,显示马丁盖尔性质
对数图检查时间序列是否是没有任何趋势的随机的。对于随机时间序列,其滞后图显示没有结构。前述图表显示了明显的线性趋势;也就是说,我们可能成功地用自回归模型进行建模。
创建自相关图
自相关图可视化了特定时间点的价格与滞后若干期价格之间的关系。
我们可以使用pandas.plotting.autocorrelation_plot(...)
方法将滞后值绘制在x轴上,将价格与指定值滞后的价格之间的相关性绘制在y轴上:
fig, ax = plt.subplots(1, figsize=(12, 6)) pd.plotting.autocorrelation_plot(time_series['A'], ax=ax)
我们可以看到随着滞后值的增加,自相关逐渐恶化:
图 5.25 – 绘制滞后值与价格和指定值滞后的自相关之间关系的图表
自相关图总结了时间序列的随机性。对于随机时间序列,所有滞后相关性都会接近于 0。对于非随机时间序列,至少一个滞后相关性会显著非零。
摘要
在本章中,我们学习了如何使用 Matplotlib 创建 pandas DataFrame 的视觉上吸引人的图表。虽然我们可以计算许多数值统计量,但图表通常更快地提供更深入的洞察力。您应该尽可能绘制尽可能多的不同图表,因为每个图表都提供了数据的不同视角。
在下一章中,我们将学习如何在 Python 中执行统计测试并估计统计模型。