Python 金融编程第二版(GPT 重译)(四)(1)

简介: Python 金融编程第二版(GPT 重译)(四)

第八章:金融时间序列

时间的唯一目的是让一切不是同时发生。

阿尔伯特·爱因斯坦

金融时间序列数据是金融领域最重要的数据类型之一。这是按日期和/或时间索引的数据。例如,随着时间的推移,股票价格代表金融时间序列数据。类似地,随时间变化的欧元/美元汇率代表金融时间序列;汇率在较短的时间间隔内报价,一系列这样的报价则是汇率的时间序列。

没有任何金融学科能够不考虑时间因素而存在。这与物理学和其他科学基本相同。在 Python 中处理时间序列数据的主要工具是pandaspandas的原始和主要作者 Wes McKinney 在 AQR Capital Management,一家大型对冲基金的分析员时开始开发这个库。可以肯定地说pandas是从头开始设计用于处理金融时间序列数据的。

本章主要基于两个以逗号分隔值(CSV)文件形式的金融时间序列数据集。它沿以下线路进行:

“金融数据”

这一部分介绍了使用pandas处理金融时间序列数据的基础知识:数据导入,导出摘要统计信息,计算随时间变化的数据和重采样。

“滚动统计”

在金融分析中,滚动统计起着重要作用。这些统计数据通常在一个固定的时间间隔内进行计算,并在整个数据集上“滚动前进”。简单移动平均线(SMAs)是一个流行的例子。这一部分说明了pandas如何支持计算这种统计数据。

“相关性分析”

这一部分提供了一个基于标普 500 股票指数和 VIX 波动率指数的金融时间序列数据的案例研究。它为两个指数都呈现负相关的模式提供了一些支持。

“高频数据”

高频数据或者说 tick 数据在金融领域已经变得司空见惯。这一部分处理 tick 数据。pandas再次在处理这样的数据集时表现强大。

金融数据

这一部分处理的是一个以 CSV 文件形式存储的本地金融数据集。从技术上讲,这些文件只是由逗号分隔单个值的数据行结构的文本文件。在导入数据之前,首先进行一些软件包导入和自定义。

In [1]: import numpy as np
        import pandas as pd
        from pylab import mpl, plt
        plt.style.use('seaborn')
        mpl.rcParams['font.family'] = 'serif'
        %matplotlib inline

数据导入

pandas提供了许多不同的函数和DataFrame方法来导入以不同格式存储的数据(CSV、SQL、Excel 等)以及将数据导出为不同的格式(详见第九章)。下面的代码使用pd.read_csv()函数从 CSV 文件中导入时间序列数据集。¹

In [2]: filename = '../../source/tr_eikon_eod_data.csv'  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [3]: !head -5 $filename  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
        Date,AAPL.O,MSFT.O,INTC.O,AMZN.O,GS.N,SPY,.SPX,.VIX,EUR=,XAU=,GDX,GLD
        2010-01-04,30.57282657,30.95,20.88,133.9,173.08,113.33,1132.99,20.04,1.4411,1120.0,47.71,109.8
        2010-01-05,30.625683660000004,30.96,20.87,134.69,176.14,113.63,1136.52,19.35,1.4368,1118.65,48.17,109.7
        2010-01-06,30.138541290000003,30.77,20.8,132.25,174.26,113.71,1137.14,19.16,1.4412,1138.5,49.34,111.51
        2010-01-07,30.082827060000003,30.452,20.6,130.0,177.67,114.19,1141.69,19.06,1.4318,1131.9,49.1,110.82
In [4]: data = pd.read_csv(filename,  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
                           index_col=0, ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
                           parse_dates=True)  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
In [5]: data.info()  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
        <class 'pandas.core.frame.DataFrame'>
        DatetimeIndex: 1972 entries, 2010-01-04 to 2017-10-31
        Data columns (total 12 columns):
        AAPL.O    1972 non-null float64
        MSFT.O    1972 non-null float64
        INTC.O    1972 non-null float64
        AMZN.O    1972 non-null float64
        GS.N      1972 non-null float64
        SPY       1972 non-null float64
        .SPX      1972 non-null float64
        .VIX      1972 non-null float64
        EUR=      1972 non-null float64
        XAU=      1972 non-null float64
        GDX       1972 non-null float64
        GLD       1972 non-null float64
        dtypes: float64(12)
        memory usage: 200.3 KB


指定路径和文件名。


显示原始数据的前五行(Linux/Mac)。


传递给pd.read_csv()函数的文件名。


这指定第一列将被处理为索引。


这另外指定索引值的类型为日期时间。


结果的DataFrame对象。

在这个阶段,金融分析师可能会通过检查数据或将其可视化(参见图 8-1)来首次查看数据。

In [6]: data.head()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[6]:                AAPL.O  MSFT.O  INTC.O  AMZN.O    GS.N     SPY     .SPX   .VIX  \
        Date
        2010-01-04  30.572827  30.950   20.88  133.90  173.08  113.33  1132.99  20.04
        2010-01-05  30.625684  30.960   20.87  134.69  176.14  113.63  1136.52  19.35
        2010-01-06  30.138541  30.770   20.80  132.25  174.26  113.71  1137.14  19.16
        2010-01-07  30.082827  30.452   20.60  130.00  177.67  114.19  1141.69  19.06
        2010-01-08  30.282827  30.660   20.83  133.52  174.31  114.57  1144.98  18.13
                      EUR=     XAU=    GDX     GLD
        Date
        2010-01-04  1.4411  1120.00  47.71  109.80
        2010-01-05  1.4368  1118.65  48.17  109.70
        2010-01-06  1.4412  1138.50  49.34  111.51
        2010-01-07  1.4318  1131.90  49.10  110.82
        2010-01-08  1.4412  1136.10  49.84  111.37
In [7]: data.tail()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[7]:             AAPL.O  MSFT.O  INTC.O   AMZN.O    GS.N     SPY     .SPX   .VIX  \
        Date
        2017-10-25  156.41   78.63   40.78   972.91  241.71  255.29  2557.15  11.23
        2017-10-26  157.41   78.76   41.35   972.43  241.72  255.62  2560.40  11.30
        2017-10-27  163.05   83.81   44.40  1100.95  241.71  257.71  2581.07   9.80
        2017-10-30  166.72   83.89   44.37  1110.85  240.89  256.75  2572.83  10.50
        2017-10-31  169.04   83.18   45.49  1105.28  242.48  257.15  2575.26  10.18
                      EUR=     XAU=    GDX     GLD
        Date
        2017-10-25  1.1812  1277.01  22.83  121.35
        2017-10-26  1.1650  1266.73  22.43  120.33
        2017-10-27  1.1608  1272.60  22.57  120.90
        2017-10-30  1.1649  1275.86  22.76  121.13
        2017-10-31  1.1644  1271.20  22.48  120.67
In [8]: data.plot(figsize=(10, 12), subplots=True)  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
        # plt.savefig('../../images/ch08/fts_01.png');


前五行 …


… 最后五行显示。


这通过多个子图可视化完整数据集。


图 8-1. 金融时间序列数据的线图

使用的数据来自汤森路透(TR)Eikon 数据 API。在 TR 世界中,金融工具的符号称为“路透社仪器代码”或RICs。单个RICs代表的金融工具是:

In [9]: instruments = ['Apple Stock', 'Microsoft Stock',
                       'Intel Stock', 'Amazon Stock', 'Goldman Sachs Stock',
                       'SPDR S&P 500 ETF Trust', 'S&P 500 Index',
                       'VIX Volatility Index', 'EUR/USD Exchange Rate',
                       'Gold Price', 'VanEck Vectors Gold Miners ETF',
                       'SPDR Gold Trust']
In [10]: for pari in zip(data.columns, instruments):
             print('{:8s} | {}'.format(pari[0], pari[1]))
         AAPL.O   | Apple Stock
         MSFT.O   | Microsoft Stock
         INTC.O   | Intel Stock
         AMZN.O   | Amazon Stock
         GS.N     | Goldman Sachs Stock
         SPY      | SPDR S&P 500 ETF Trust
         .SPX     | S&P 500 Index
         .VIX     | VIX Volatility Index
         EUR=     | EUR/USD Exchange Rate
         XAU=     | Gold Price
         GDX      | VanEck Vectors Gold Miners ETF
         GLD      | SPDR Gold Trust

摘要统计

下一步,金融分析师可能会采取的步骤是查看数据集的不同摘要统计信息,以了解它的“感觉”。

In [11]: data.info()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
         <class 'pandas.core.frame.DataFrame'>
         DatetimeIndex: 1972 entries, 2010-01-04 to 2017-10-31
         Data columns (total 12 columns):
         AAPL.O    1972 non-null float64
         MSFT.O    1972 non-null float64
         INTC.O    1972 non-null float64
         AMZN.O    1972 non-null float64
         GS.N      1972 non-null float64
         SPY       1972 non-null float64
         .SPX      1972 non-null float64
         .VIX      1972 non-null float64
         EUR=      1972 non-null float64
         XAU=      1972 non-null float64
         GDX       1972 non-null float64
         GLD       1972 non-null float64
         dtypes: float64(12)
         memory usage: 200.3 KB
In [12]: data.describe().round(2)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[12]:         AAPL.O   MSFT.O   INTC.O   AMZN.O     GS.N      SPY     .SPX     .VIX  \
         count  1972.00  1972.00  1972.00  1972.00  1972.00  1972.00  1972.00  1972.00
         mean     86.53    40.59    27.70   401.15   163.61   172.84  1727.54    17.21
         std      34.04    14.39     5.95   257.12    37.17    42.33   424.35     5.92
         min      27.44    23.01    17.66   108.61    87.70   102.20  1022.58     9.19
         25%      57.57    28.12    22.23   202.66   144.23   132.64  1325.53    13.25
         50%      84.63    36.54    26.41   306.42   162.09   178.80  1783.81    15.65
         75%     111.87    50.08    33.74   559.45   184.11   208.01  2080.15    19.20
         max     169.04    83.89    45.49  1110.85   252.89   257.71  2581.07    48.00
                   EUR=     XAU=      GDX      GLD
         count  1972.00  1972.00  1972.00  1972.00
         mean      1.25  1352.47    34.50   130.60
         std       0.12   195.38    15.44    19.46
         min       1.04  1051.36    12.47   100.50
         25%       1.13  1214.56    22.22   116.77
         50%       1.29  1288.82    26.59   123.90
         75%       1.35  1491.98    49.77   145.43
         max       1.48  1897.10    66.63   184.59


.info()提供有关DataFrame对象的一些元信息。


.describe() 提供每列有用的标准统计数据。

提示

pandas提供了许多方法来快速查看新导入的金融时间序列数据集的概述,例如.info().describe()。它们还允许快速检查导入过程是否按预期工作(例如,DataFrame对象是否确实具有DatetimeIndex作为索引)。

当然,也有选项来自定义要推导和显示的统计信息类型。

In [13]: data.mean()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[13]: AAPL.O      86.530152
         MSFT.O      40.586752
         INTC.O      27.701411
         AMZN.O     401.154006
         GS.N       163.614625
         SPY        172.835399
         .SPX      1727.538342
         .VIX        17.209498
         EUR=         1.252613
         XAU=      1352.471593
         GDX         34.499391
         GLD        130.601856
         dtype: float64
In [14]: data.aggregate(min,  ![2                         np.mean,  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
                         np.std,  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
                         np.median,  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
                         max]  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
         ).round(2)
Out[14]:         AAPL.O  MSFT.O  INTC.O   AMZN.O    GS.N     SPY     .SPX   .VIX  EUR=  \
         min      27.44   23.01   17.66   108.61   87.70  102.20  1022.58   9.19  1.04
         mean     86.53   40.59   27.70   401.15  163.61  172.84  1727.54  17.21  1.25
         std      34.04   14.39    5.95   257.12   37.17   42.33   424.35   5.92  0.12
         median   84.63   36.54   26.41   306.42  162.09  178.80  1783.81  15.65  1.29
         max     169.04   83.89   45.49  1110.85  252.89  257.71  2581.07  48.00  1.48
                    XAU=    GDX     GLD
         min     1051.36  12.47  100.50
         mean    1352.47  34.50  130.60
         std      195.38  15.44   19.46
         median  1288.82  26.59  123.90
         max     1897.10  66.63  184.59


每列的均值。


每列的最小值。


每列的均值。


每列的标准偏差。


每列的最大值。


使用.aggregate()方法还允许传递自定义函数。

随时间变化

大多数统计分析方法,例如,通常基于时间序列随时间的变化,而不是绝对值本身。有多种选项可以计算时间序列随时间的变化,包括:绝对差异、百分比变化和对数(对数)收益。

首先是绝对差异,对于这个pandas提供了一个特殊的方法。

In [15]: data.diff().head()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[15]:               AAPL.O  MSFT.O  INTC.O  AMZN.O  GS.N   SPY  .SPX  .VIX    EUR=  \
         Date
         2010-01-04       NaN     NaN     NaN     NaN   NaN   NaN   NaN   NaN     NaN
         2010-01-05  0.052857   0.010   -0.01    0.79  3.06  0.30  3.53 -0.69 -0.0043
         2010-01-06 -0.487142  -0.190   -0.07   -2.44 -1.88  0.08  0.62 -0.19  0.0044
         2010-01-07 -0.055714  -0.318   -0.20   -2.25  3.41  0.48  4.55 -0.10 -0.0094
         2010-01-08  0.200000   0.208    0.23    3.52 -3.36  0.38  3.29 -0.93  0.0094
                      XAU=   GDX   GLD
         Date
         2010-01-04    NaN   NaN   NaN
         2010-01-05  -1.35  0.46 -0.10
         2010-01-06  19.85  1.17  1.81
         2010-01-07  -6.60 -0.24 -0.69
         2010-01-08   4.20  0.74  0.55
In [16]: data.diff().mean()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[16]: AAPL.O    0.070252
         MSFT.O    0.026499
         INTC.O    0.012486
         AMZN.O    0.492836
         GS.N      0.035211
         SPY       0.072968
         .SPX      0.731745
         .VIX     -0.005003
         EUR=     -0.000140
         XAU=      0.076712
         GDX      -0.012801
         GLD       0.005515
         dtype: float64


.diff()提供了两个索引值之间的绝对变化。


当然,还可以应用聚合操作。

从统计学的角度来看,绝对变化不是最佳选择,因为它们依赖于时间序列数据本身的比例。因此,通常更喜欢百分比变化。以下代码推导了金融背景下的百分比变化或百分比收益(也称为:简单收益),并可视化其每列的均值(参见 图 8-2)。

In [17]: data.pct_change().round(3).head()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[17]:             AAPL.O  MSFT.O  INTC.O  AMZN.O   GS.N    SPY   .SPX   .VIX   EUR=  \
         Date
         2010-01-04     NaN     NaN     NaN     NaN    NaN    NaN    NaN    NaN    NaN
         2010-01-05   0.002   0.000  -0.000   0.006  0.018  0.003  0.003 -0.034 -0.003
         2010-01-06  -0.016  -0.006  -0.003  -0.018 -0.011  0.001  0.001 -0.010  0.003
         2010-01-07  -0.002  -0.010  -0.010  -0.017  0.020  0.004  0.004 -0.005 -0.007
         2010-01-08   0.007   0.007   0.011   0.027 -0.019  0.003  0.003 -0.049  0.007
                      XAU=    GDX    GLD
         Date
         2010-01-04    NaN    NaN    NaN
         2010-01-05 -0.001  0.010 -0.001
         2010-01-06  0.018  0.024  0.016
         2010-01-07 -0.006 -0.005 -0.006
         2010-01-08  0.004  0.015  0.005
In [18]: data.pct_change().mean().plot(kind='bar', figsize=(10, 6));  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
         # plt.savefig('../../images/ch08/fts_02.png');


.pct_change()计算两个索引值之间的百分比变化。


结果的均值作为条形图可视化。


图 8-2. 百分比变化的均值作为条形图

作为百分比收益的替代,可以使用对数收益。在某些情况下,它们更容易处理,因此在金融背景下通常更受欢迎。² 图 8-3 展示了单个金融时间序列的累积对数收益。这种类型的绘图导致某种形式的归一化

In [19]: rets = np.log(data / data.shift(1))  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [20]: rets.head().round(3)  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[20]:             AAPL.O  MSFT.O  INTC.O  AMZN.O   GS.N    SPY   .SPX   .VIX   EUR=  \
         Date
         2010-01-04     NaN     NaN     NaN     NaN    NaN    NaN    NaN    NaN    NaN
         2010-01-05   0.002   0.000  -0.000   0.006  0.018  0.003  0.003 -0.035 -0.003
         2010-01-06  -0.016  -0.006  -0.003  -0.018 -0.011  0.001  0.001 -0.010  0.003
         2010-01-07  -0.002  -0.010  -0.010  -0.017  0.019  0.004  0.004 -0.005 -0.007
         2010-01-08   0.007   0.007   0.011   0.027 -0.019  0.003  0.003 -0.050  0.007
                      XAU=    GDX    GLD
         Date
         2010-01-04    NaN    NaN    NaN
         2010-01-05 -0.001  0.010 -0.001
         2010-01-06  0.018  0.024  0.016
         2010-01-07 -0.006 -0.005 -0.006
         2010-01-08  0.004  0.015  0.005
In [21]: rets.cumsum().apply(np.exp).plot(figsize=(10, 6));  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
         # plt.savefig('../../images/ch08/fts_03.png');


这以向量化方式计算对数收益。


结果的子集。


这绘制了随时间累积的对数收益;首先调用.cumsum()方法,然后将np.exp()应用于结果。


图 8-3. 随时间累积的对数收益

重采样

对于金融时间序列数据,重采样是一项重要的操作。通常,这采取上采样的形式,意味着例如,具有每日观测的时间序列被重采样为具有每周或每月观测的时间序列。这也可能意味着将金融 Tick 数据系列重采样为一分钟间隔(也称为:柱)。

In [22]: data.resample('1w', label='right').last().head()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
Out[22]:                AAPL.O  MSFT.O  INTC.O  AMZN.O    GS.N     SPY     .SPX   .VIX  \
         Date
         2010-01-10  30.282827   30.66   20.83  133.52  174.31  114.57  1144.98  18.13
         2010-01-17  29.418542   30.86   20.80  127.14  165.21  113.64  1136.03  17.91
         2010-01-24  28.249972   28.96   19.91  121.43  154.12  109.21  1091.76  27.31
         2010-01-31  27.437544   28.18   19.40  125.41  148.72  107.39  1073.87  24.62
         2010-02-07  27.922829   28.02   19.47  117.39  154.16  106.66  1066.19  26.11
                       EUR=     XAU=    GDX     GLD
         Date
         2010-01-10  1.4412  1136.10  49.84  111.37
         2010-01-17  1.4382  1129.90  47.42  110.86
         2010-01-24  1.4137  1092.60  43.79  107.17
         2010-01-31  1.3862  1081.05  40.72  105.96
         2010-02-07  1.3662  1064.95  42.41  104.68
In [23]: data.resample('1m', label='right').last().head()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
Out[23]:                AAPL.O   MSFT.O  INTC.O  AMZN.O    GS.N       SPY     .SPX  \
         Date
         2010-01-31  27.437544  28.1800   19.40  125.41  148.72  107.3900  1073.87
         2010-02-28  29.231399  28.6700   20.53  118.40  156.35  110.7400  1104.49
         2010-03-31  33.571395  29.2875   22.29  135.77  170.63  117.0000  1169.43
         2010-04-30  37.298534  30.5350   22.84  137.10  145.20  118.8125  1186.69
         2010-05-31  36.697106  25.8000   21.42  125.46  144.26  109.3690  1089.41
                      .VIX    EUR=     XAU=    GDX      GLD
         Date
         2010-01-31  24.62  1.3862  1081.05  40.72  105.960
         2010-02-28  19.50  1.3625  1116.10  43.89  109.430
         2010-03-31  17.59  1.3510  1112.80  44.41  108.950
         2010-04-30  22.05  1.3295  1178.25  50.51  115.360
         2010-05-31  32.07  1.2267  1213.81  49.86  118.881
In [24]: rets.cumsum().resample('1m', label='right').last(
                                   ).plot(figsize=(10, 6));  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
         # plt.savefig('../../images/ch08/fts_04.png');


EOD 数据被重采样为


结果的子集。


这绘制了随时间累积的对数收益;首先调用.cumsum()方法,然后将np.exp()应用于结果。


图 8-4. 随时间重采样的累积对数收益(每月)
注意

在重新取样时,默认情况下,pandas采用区间的左标签(或索引值)。为了保持金融一致性,请确保使用右标签(索引值)和通常是区间中最后一个可用数据点。否则,可能会在金融分析中引入预见偏差。^(3)

滚动统计

在金融传统中,通常称为滚动统计,也称为金融指标金融研究。这样的滚动统计是金融图表分析师和技术交易员的基本工具,例如。本节仅处理单个金融时间序列。

In [25]: sym = 'AAPL.O'
In [26]: data = pd.DataFrame(data[sym])
In [27]: data.tail()
Out[27]:             AAPL.O
         Date
         2017-10-25  156.41
         2017-10-26  157.41
         2017-10-27  163.05
         2017-10-30  166.72
         2017-10-31  169.04

概览

使用pandas很容易得出标准滚动统计。

In [28]: window = 20  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [29]: data['min'] = data[sym].rolling(window=window).min()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [30]: data['mean'] = data[sym].rolling(window=window).mean()  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
In [31]: data['std'] = data[sym].rolling(window=window).std()  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
In [32]: data['median'] = data[sym].rolling(window=window).median()  ![5](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/5.png)
In [33]: data['max'] = data[sym].rolling(window=window).max()  ![6](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/6.png)
In [34]: data['ewma'] = data[sym].ewm(halflife=0.5, min_periods=window).mean()  ![7](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/7.png)


定义窗口,即要包含的索引值的数量。


计算滚动最小值。


计算滚动均值。


计算滚动标准差。


计算滚动中位数。


计算滚动最大值。


这将计算指数加权移动平均值,衰减以半衰期0.5来计算。

要推导出更专业的金融指标,通常需要使用其他软件包(例如,使用Cufflinks进行金融图表,参见“交互式二维绘图”)。也可以通过.apply()方法轻松地应用自定义指标。

下面的代码显示了部分结果,并可视化了计算的滚动统计的选择部分(参见图 8-5)。

In [35]: data.dropna().head()
Out[35]:                AAPL.O        min       mean       std     median        max  \
         Date
         2010-02-01  27.818544  27.437544  29.580892  0.933650  29.821542  30.719969
         2010-02-02  27.979972  27.437544  29.451249  0.968048  29.711113  30.719969
         2010-02-03  28.461400  27.437544  29.343035  0.950665  29.685970  30.719969
         2010-02-04  27.435687  27.435687  29.207892  1.021129  29.547113  30.719969
         2010-02-05  27.922829  27.435687  29.099892  1.037811  29.419256  30.719969
                          ewma
         Date
         2010-02-01  27.805432
         2010-02-02  27.936337
         2010-02-03  28.330134
         2010-02-04  27.659299
         2010-02-05  27.856947
In [36]: ax = data[['min', 'mean', 'max']].iloc[-200:].plot(
             figsize=(10, 6), style=['g--', 'r--', 'g--'], lw=0.8)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
         data[sym].iloc[-200:].plot(ax=ax, lw=2.0);  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
         # plt.savefig('../../images/ch08/fts_05.png');


绘制最后 200 个数据行的三个滚动统计。


将原始时间序列数据添加到图表中。


图 8-5。最小、平均、最大值的滚动统计

技术分析示例

与基本分析相比,滚动统计是所谓的技术分析中的主要工具,基本分析侧重于财务报告和被分析股票公司的战略位置等方面。

基于技术分析的几十年历史的交易策略基于两个简单移动平均线(SMAs)。这个想法是,当短期 SMA 高于长期 SMA 时,交易员应该持有一支股票(或者一般的金融工具),当情况相反时,应该空仓。这些概念可以通过pandasDataFrame对象的功能来精确描述。

当给定了window参数规范并且有足够的数据时,通常才会计算滚动统计。如图 8-6 所示,SMAs 时间序列仅从有足够数据的那天开始。

In [37]: data['SMA1'] = data[sym].rolling(window=42).mean()  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [38]: data['SMA2'] = data[sym].rolling(window=252).mean()  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
In [39]: data[[sym, 'SMA1', 'SMA2']].tail()
Out[39]:             AAPL.O        SMA1        SMA2
         Date
         2017-10-25  156.41  157.610952  139.862520
         2017-10-26  157.41  157.514286  140.028472
         2017-10-27  163.05  157.517619  140.221210
         2017-10-30  166.72  157.597857  140.431528
         2017-10-31  169.04  157.717857  140.651766
In [40]: data[[sym, 'SMA1', 'SMA2']].plot(figsize=(10, 6));  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
         # plt.savefig('../../images/ch08/fts_06.png');


计算短期 SMA 的值。


计算长期 SMA 的值。


可视化股价数据和两条 SMAs 时间序列。


图 8-6. 苹果股价和两条简单移动平均线

在这个背景下,简单移动平均线(SMAs)仅仅是实现目标的手段。它们被用来推导出实施交易策略的定位。图 8-7 通过数值1来可视化多头头寸,数值-1来可视化空头头寸。头寸的变化(在视觉上)由表示 SMAs 时间序列的两条线的交叉触发。

In [41]: data.dropna(inplace=True)  ![1](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/1.png)
In [42]: data['positions'] = np.where(data['SMA1'] > data['SMA2'],  ![2](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/2.png)
                                      1,  ![3](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/3.png)
                                      -1)  ![4](https://gitee.com/OpenDocCN/ibooker-quant-zh/raw/master/docs/py-fin-2e/img/4.png)
In [43]: ax = data[[sym, 'SMA1', 'SMA2', 'positions']].plot(figsize=(10, 6),
                                                       secondary_y='positions')
         ax.get_legend().set_bbox_to_anchor((0.25, 0.85));
         # plt.savefig('../../images/ch08/fts_07.png');


仅保留完整的数据行。


如果短期 SMA 值大于长期 SMA 值…


…买入股票(放置1)…


…否则卖空股票(放置-1)。


图 8-7. 苹果股价,两条简单移动平均线和头寸

在这里隐含地推导出的交易策略本质上只导致了很少的交易:只有当头寸价值变化(即发生交叉)时,才会进行交易。包括开仓和平仓交易,在总计中这将只增加到六次交易。


Python 金融编程第二版(GPT 重译)(四)(2)https://developer.aliyun.com/article/1559360

相关文章
|
5天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
5天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
5天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
7天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
6天前
|
机器学习/深度学习 存储 算法
探索Python编程:从基础到高级应用
【10月更文挑战第38天】本文旨在引导读者从Python的基础知识出发,逐渐深入到高级编程概念。通过简明的语言和实际代码示例,我们将一起探索这门语言的魅力和潜力,理解它如何帮助解决现实问题,并启发我们思考编程在现代社会中的作用和意义。
|
7天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
|
7天前
|
人工智能 数据挖掘 程序员
Python编程入门:从零到英雄
【10月更文挑战第37天】本文将引导你走进Python编程的世界,无论你是初学者还是有一定基础的开发者,都能从中受益。我们将从最基础的语法开始讲解,逐步深入到更复杂的主题,如数据结构、面向对象编程和网络编程等。通过本文的学习,你将能够编写出自己的Python程序,实现各种功能。让我们一起踏上Python编程之旅吧!
|
4月前
|
存储 SQL 数据库
Python 金融编程第二版(GPT 重译)(四)(4)
Python 金融编程第二版(GPT 重译)(四)
49 3
|
4月前
|
存储 NoSQL 索引
Python 金融编程第二版(GPT 重译)(一)(4)
Python 金融编程第二版(GPT 重译)(一)
61 2
|
4月前
|
存储 机器学习/深度学习 关系型数据库
Python 金融编程第二版(GPT 重译)(四)(5)
Python 金融编程第二版(GPT 重译)(四)
35 2