Python金融大數據分析:用pandas處理金融時間序列數據的基礎知識

時間是阻止所有事情同時發生的力量。——雷•卡明斯

本節使用的是以CSV文件形式在本地存儲的金融數據集形式爲本地存儲的CSV文件。從技術上講,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

8.1.1 數據導入

pandas提供不同的函數和DataFrame方法,以導入不同存儲格式(CSV、SQL、Excel等)的數據,並將數據導出爲不同格式(詳見第9章)。下面的代碼通過pd.read_csv()函數導入CSV[1]文件中的時間序列數據:

In [2]: filename = '../../source/tr_eikon_eod_data.csv' ❶

In [3]: f = open(filename, 'r') ❷
        f.readlines()[:5] ❷
Out[3]: ['Date,AAPL.O,MSFT.O,INTC.O,AMZN.O,GS.N,SPY,.SPX,.VIX,EUR=,XAU=,GDX,
        ,GLD\n',
         '2010-01-01,,,,,,,,,1.4323,1096.35,,\n',
         '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\n',
         '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\n',
         '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\n']
In [4]: data = pd.read_csv(filename, ❸
                           index_col=0, ❹
                           parse_dates=True) ❺

In [5]: data.info() ❻
        <class 'pandas.core.frame.DataFrame'>
        DatetimeIndex: 2216 entries, 2010-01-01 to 2018-06-29
        Data columns (total 12 columns):
        AAPL.O    2138 non-null float64
        MSFT.O    2138 non-null float64
        INTC.O    2138 non-null float64
        AMZN.O    2138 non-null float64
        GS.N      2138 non-null float64
        SPY       2138 non-null float64
        .SPX      2138 non-null float64
        .VIX      2138 non-null float64
        EUR=      2216 non-null float64
        XAU=      2211 non-null float64
        GDX       2138 non-null float64
        GLD       2138 non-null float64
        dtypes: float64(12)
        memory usage: 225.1 KB

❶ 指定路徑和文件名。

❷ 顯示原始數據(Linux/Mac)的前5行。

❸ 傳遞給pd.read_scv()函數的文件名。

❹ 指定第一列作爲索引處理。

❺ 指定索引值爲datetime類型。

❻ 結果爲DataFrame對象。

在這一階段,金融分析師可能首先觀察數據,對其進行檢查或者可視化(見圖8-1):

In [6]: data.head() ❶
Out[6]:
                   AAPL.O MSFT.O INTC.O AMZN.O  GS.N   SPY   .SPX .VIX \
    Date
    2010-01-01        NaN    NaN    NaN    NaN   NaN   NaN    NaN  NaN
    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

                  EUR=    XAU=   GDX    GLD
    Date
    2010-01-01  1.4323 1096.35   NaN    NaN
    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

In [7]: data.tail() ❷
Out[7]:
                AAPL.O MSFT.O INTC.O  AMZN.O   GS.N    SPY   .SPX.VIX \
    Date
    2018-06-25  182.17  98.39  50.71 1663.15 221.54 271.00 2717.07 17.33
    2018-06-26  184.43  99.08  49.67 1691.09 221.58 271.60 2723.06 15.92
    2018-06-27  184.16  97.54  48.76 1660.51 220.18 269.35 2699.63 17.91
    2018-06-28  185.50  98.63  49.25 1701.45 223.42 270.89 2716.31 16.85
    2018-06-29  185.11  98.61  49.71 1699.80 220.57 271.28 2718.37 16.09

                  EUR=    XAU=   GDX    GLD
    Date
    2018-06-25  1.1702 1265.00 22.01 119.89
    2018-06-26  1.1645 1258.64 21.95 119.26
    2018-06-27  1.1552 1251.62 21.81 118.58
    2018-06-28  1.1567 1247.88 21.93 118.22
    2018-06-29  1.1683 1252.25 22.31 118.65

    In [8]: data.plot(figsize=(10, 12), subplots=True); ❸

圖8-1 以線圖表示的金融時間序列數據

❶ 前5行。

❷最後5行顯示。

❸ 這個語句通過多個子圖來可視化整個數據集。

這裏使用的數據來自Thomson Reuters (TR) Eikon Data API。TR金融工具代碼稱作路透金融工具代碼(RIC)。RIC表示的金融工具爲:

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 ric, name in zip(data.columns, instruments):
             print('{:8s} | {}'.format(ric, name))
         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

8.1.2 彙總統計

金融分析師採取的下一個步驟是觀察不同的數據集彙總統計,從而對其有個總體的“感覺”:

In [11]: data.info() ❶
         <class 'pandas.core.frame.DataFrame'>
         DatetimeIndex: 2216 entries, 2010-01-01 to 2018-06-29
         Data columns (total 12 columns):
         AAPL.O    2138 non-null float64
         MSFT.O    2138 non-null float64
         INTC.O    2138 non-null float64
         AMZN.O    2138 non-null float64
         GS.N      2138 non-null float64
         SPY       2138 non-null float64
         .SPX      2138 non-null float64
         .VIX      2138 non-null float64
         EUR=      2216 non-null float64
         XAU=      2211 non-null float64
         GDX       2138 non-null float64
         GLD       2138 non-null float64
         dtypes: float64(12)
         memory usage: 225.1 KB

In [12]: data.describe().round(2) ❷
Out[12]:
            AAPL.O  MSFT.O  INTC.O AMZN.O    GS.N    SPY   .SPX .VIX \
    Count  2138.00 2138.00 2138.00 2138.00 2138.00 2138.00 2138.00 2138.00
    mean     93.46   44.56   29.36 480.46  170.22 180.32 1802.71  17.03
    std      40.55   19.53    8.17 372.31   42.48  48.19 483.34   5.88
    min      27.44   23.01   17.66 108.61   87.70 102.20 1022.58   9.14
    25%      60.29   28.57   22.51 213.60  146.61 133.99 1338.57  13.07
    50%      90.55   39.66   27.33 322.06  164.43 186.32 1863.08  15.58
    75%     117.24   54.37   34.71 698.85  192.13 210.99 2108.94  19.07
    max     193.98  102.49   57.08 1750.08  273.38 286.58 2872.87  48.00

               EUR=    XAU=     GDX     GLD
    count   2216.00 2211.00 2138.00 2138.00
    mean       1.25 1349.01   33.57  130.09
    std        0.11 188.75    15.17   18.78
    min        1.04 1051.36   12.47  100.50
    25%        1.13 1221.53   22.14  117.40
    50%        1.27 1292.61   25.62  124.00
    75%        1.35 1428.24   48.34  139.00
    max        1.48 1898.99   66.63  184.59

❶ info()給出DataFrame對象的相關元信息。

❷ describe()提供每列的實用標準統計量。

 

敏銳的洞察力

pandas提供了許多方法如info和describe(),可以獲得新導入的金融時間序列數據集的簡單概況。它們還能快捷地檢查導入程序是否按照要求進行(例如,DataFrame對象是否真正包含DatetimeIndex類型的索引)。

當然,pandas也提供自定義統計類型及顯示方式的選項:

In [13]: data.mean() ❶
Out[13]: AAPL.O     93.455973
         MSFT.O     44.561115
         INTC.O     29.364192
         AMZN.O    480.461251
         GS.N      170.216221
         SPY       180.323029
         .SPX     1802.713106
         .VIX       17.027133
         EUR=        1.248587
         XAU=     1349.014130
         GDX        33.566525
         GLD       130.086590
         dtype: float64

In [14]: data.aggregate([min, ❷
                         np.mean, ❸
                         np.std, ❹
                         np.median, ❺
                         max] ❻
         ).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.14 1.04
    mean    93.46  44.56  29.36  480.46 170.22 180.32 1802.71 17.03 1.25
    std     40.55  19.53   8.17  372.31  42.48  48.19  483.34 5.88 0.11
    median  90.55  39.66  27.33  322.06 164.43 186.32 1863.08 15.58 1.27
    max    193.98 102.49  57.08 1750.08 273.38 286.58 2872.87 48.00 1.48

              XAU=   GDX    GLD
    min    1051.36 12.47 100.50
    mean   1349.01 33.57 130.09
    std     188.75 15.17  18.78
    median 1292.61 25.62 124.00
    max    1898.99 66.63 184.59

❶ 每列均值。

❷ 每列最小值。

❸ 每列均值。

❹ 每列標準差。

❺ 每列中位數。

❻ 每列最大值。

使用aggregate方法還可以傳遞自定義函數。

8.1.3 隨時間推移的變化

統計分析方法往往基於隨時間推移的變化,而不是絕對值。計算時間序列中的隨時變化有多種選擇,包括絕對偏差、變化率和對數回報率。

首先介紹絕對偏差,pandas爲此提供了一個特殊的方法:

In [15]: data.diff().head() ❶
Out[15]:
                  AAPL.O MSFT.O INTC.O AMZN.O  GS.N SPY .SPX .VIX EUR= \
    Date
    2010-01-01       NaN    NaN    NaN    NaN   NaN NaN NaN NaN NaN
    2010-01-04       NaN    NaN    NaN    NaN   NaN NaN NaN NaN 0.0088
    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

                 XAU=  GDX   GLD
    Date
    2010-01-01   NaN   NaN   NaN
    2010-01-04 23.65   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
In [16]: data.diff().mean() ❷
Out[16]: AAPL.O    0.064737
         MSFT.O    0.031246
         INTC.O    0.013540
         AMZN.O    0.706608
         GS.N      0.028224
         SPY       0.072103
         .SPX      0.732659
         .VIX     -0.019583
         EUR=     -0.000119
         XAU=      0.041887
         GDX      -0.015071
         GLD      -0.003455
         dtype: float64

❶ diff提供兩個索引值之間的絕對變化。

❷ 當然,還可以應用聚合運算。

從統計學角度講,絕對變化不是最優的,因爲它們與時間序列數據本身的比例相關。因此,我們通常更偏重變化率。下面的代碼可以計算金融環境裏的變動率或者回報率(也稱爲簡單回報率),並對其每列的平均值進行可視化(參見圖8-2):

In [17]: data.pct_change().round(3).head() ❶
Out[17]:
                AAPL.O MSFT.O INTC.O AMZN.O GS.N SPY .SPX .VIX EUR= \
    Date
    2010-01-01   NaN    NaN    NaN   NaN   NaN   NaN   NaN   NaN    NaN
    2010-01-04   NaN    NaN    NaN   NaN   NaN   NaN   NaN   NaN  0.006
    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

                XAU= GDX GLD
    Date
    2010-01-01    NaN    NaN    NaN
    2010-01-04  0.022    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
In [18]: data.pct_change().mean().plot(kind='bar', figsize=(10, 6)); ❷

❶ pct_change()計算兩個索引值之間的變化率。

❷ 將結果的均值可視化爲一個柱狀圖。

圖8-2 變化率均值柱狀圖

對數回報率可作爲回報率的替代品。在某些情況下,它們更容易處理,因此在金融環境中往往優先使用對數回報率。[2]

圖8-3展示了單個金融時間序列的累計對數回報率。這種類型的圖表導致了某種形式的規範化:

圖8-3 一段時間的累計對數回報率

In [19]: rets = np.log(data / data.shift(1))❶

In [20]: rets.head().round(3) ❷
Out[20]:

                AAPL.O MSFT.O INTC.O AMZN.O GS.N SPY .SPX .VIX EUR= \
    Date
    2010-01-01     NaN   NaN    NaN    NaN    NaN  NaN  NaN   NaN   NaN
    2010-01-04     NaN   NaN    NaN    NaN    NaN  NaN  NaN   NaN  0.006
    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

                 XAU= GDX GLD
    Date
    2010-01-01    NaN    NaN    NaN
    2010-01-04  0.021    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

In [21]: rets.cumsum().apply(np.exp).plot(figsize=(10, 6)); ❸

❶ 以向量的方式計算對數回報率。

❷ 結果的一個子集。

❸ 繪製一段時間的累計對數回報率圖表;首先調用cumsum()方法,然後對結果應用np.exp()。

8.1.4 重新採樣

重新採樣是金融時間序列數據的重要操作之一,通常採用向下採樣的形式,例如,分筆交易數據序列重新採樣的時間間隔爲一分鐘,也可以將每日觀察數據的時間序列重新採樣爲每週或者每月觀察數據(如圖8-4所示):

In [22]: data.resample('1w', label='right').last().head() ❶
Out[22]:
                   AAPL.O MSFT.O INTC.O AMZN.O   GS.N    SPY   .SPX .VIX \
    Date
    2010-01-03        NaN    NaN   NaN   NaN    NaN    NaN    NaN   NaN
    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

                  EUR=    XAU=   GDX    GLD
    Date
    2010-01-03  1.4323 1096.35   NaN    NaN
    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

In [23]: data.resample('1m', label='right').last().head() ❷
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.2305 1215.71 49.86 118.881

In [24]: rets.cumsum().apply(np.exp). resample('1m', label='right').last(
                                  ).plot(figsize=(10, 6)); ❸

❶ 日終數據以一週爲時間間隔重新採樣。

❷ 以一月爲時間間隔重新採樣。

❸ 這就繪製了隨時間變化的累計對數回報率圖表:首先調用cumsun(),然後對結果應用np.exp,最後進行重新採樣。

圖8-4 重採樣的累計對數回報率圖表(每月)

 

避免預見偏差

在很多情況下,pandas在重新採樣時默認使用區間的左側標籤(或者索引值)。爲了在金融業務中保持一致,請確保使用右標籤(索引值)——一般是區間內最後一個可用數據點。否則,金融分析中可能潛藏着預見偏差。

本文摘自《Python金融大數據分析 第2版》

  • 金融科技算法交易量化金融教程書籍
  • 詳細講解使用Python分析處理金融大數據的專業圖書
  • 將人工智能應用於金融開發的實戰指南,金融應用開發領域從業人員的常備讀物

《Python金融大數據分析 第2版》分爲5部分,共21章。第1部分介紹了Python在金融學中的應用,其內容涵蓋了Python用於金融行業的原因、Python的基礎架構和工具,以及Python在計量金融學中的一些具體入門實例;第2部分介紹了Python的基礎知識以及Python中非常有名的庫NumPy和pandas工具集,還介紹了面向對象編程;第3部分介紹金融數據科學的相關基本技術和方法,包括數據可視化、輸入/輸出操作和數學中與金融相關的知識等;第4部分介紹Python在算法交易上的應用,重點介紹常見算法,包括機器學習、深度神經網絡等人工智能相關算法;第5部分講解基於蒙特卡洛模擬開發期權及衍生品定價的應用,其內容涵蓋了估值框架的介紹、金融模型的模擬、衍生品的估值、投資組合的估值等知識。 

《Python金融大數據分析 第2版》本書適合對使用Python進行大數據分析、處理感興趣的金融行業開發人員閱讀。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章