【问题标题】:How to calculate Volume Weighted Average Price (VWAP) using a pandas dataframe with ask and bid price?如何使用带有卖价和买价的 pandas 数据框计算成交量加权平均价格(VWAP)?
【发布时间】:2019-09-06 01:03:47
【问题描述】:

如果我的表格如下所示,我如何创建另一个名为 vwap 的列来计算 vwap?

             time            bid_size   bid       ask  ask_size trade trade_size phase  
0   2019-01-07 07:45:01.064515  495   152.52    152.54    19     NaN      NaN    OPEN   
1   2019-01-07 07:45:01.110072  31    152.53    152.54    19     NaN      NaN    OPEN   
2   2019-01-07 07:45:01.116596  32    152.53    152.54    19     NaN      NaN    OPEN   
3   2019-01-07 07:45:01.116860  32    152.53    152.54    21     NaN      NaN    OPEN   
4   2019-01-07 07:45:01.116905  34    152.53    152.54    21     NaN      NaN    OPEN   
5   2019-01-07 07:45:01.116982  34    152.53    152.54    31     NaN      NaN    OPEN   
6   2019-01-07 07:45:01.147901  38    152.53    152.54    31     NaN      NaN    OPEN   
7   2019-01-07 07:45:01.189971  38    152.53    152.54    31     ask     15.0    OPEN   
8   2019-01-07 07:45:01.189971  38    152.53    152.54    16     NaN      NaN    OPEN   
9   2019-01-07 07:45:01.190766  37    152.53    152.54    16     NaN      NaN    OPEN   
10  2019-01-07 07:45:01.190856  37    152.53    152.54    15     NaN      NaN    OPEN
11  2019-01-07 07:45:01.190856  37    152.53    152.54    16     ask      1.0    OPEN   
12  2019-01-07 07:45:01.193938  37    152.53    152.55   108     NaN      NaN    OPEN   
13  2019-01-07 07:45:01.193938  37    152.53    152.54    15     ask     15.0    OPEN   
14  2019-01-07 07:45:01.194326  2     152.54    152.55   108     NaN      NaN    OPEN   
15  2019-01-07 07:45:01.194453  2     152.54    152.55    97     NaN      NaN    OPEN   
16  2019-01-07 07:45:01.194479  6     152.54    152.55    97     NaN      NaN    OPEN   
17  2019-01-07 07:45:01.194507  19    152.54    152.55    97     NaN      NaN    OPEN   
18  2019-01-07 07:45:01.194532  19    152.54    152.55    77     NaN      NaN    OPEN   
19  2019-01-07 07:45:01.194598  19    152.54    152.55    79     NaN      NaN    OPEN   

对不起,表格不清楚,但最右边的第二列是trade_size,在它的左边是trade,它显示了交易的一面(买或卖)。如果 trade_size 和 trade 都是 NaN,则表明在该时间戳没有发生任何交易。

如果 df['trade'] == "ask",交易价格将是 'ask' 列中的价格,如果 df['trade] == "bid",交易价格将是 '列中的价格出价'。既然有2个价格,请问如何计算vwap,df['vwap']?

我的想法是使用 np.cumsum()。

【问题讨论】:

标签: python-3.x pandas numpy dataframe quantitative-finance


【解决方案1】:

您可以使用np.where 为您提供正确列(bid 或ask)中的价格,具体取决于trade 列中的值。请注意,这会在没有交易发生时为您提供出价,但是因为这会乘以 NaN 交易规模,所以这无关紧要。我还转发了 VWAP。

volume = df['trade_size']
price = np.where(df['trade'].eq('ask'), df['ask'], df['bid'])  
df = df.assign(VWAP=((volume * price).cumsum() / vol.cumsum()).ffill())

>>> df
        time    bid_size    bid ask ask_size    trade   trade_size  phase   VWAP
0   2019-01-07  07:45:01.064515 495 152.52  152.54  19  NaN NaN OPEN    NaN
1   2019-01-07  07:45:01.110072 31  152.53  152.54  19  NaN NaN OPEN    NaN
2   2019-01-07  07:45:01.116596 32  152.53  152.54  19  NaN NaN OPEN    NaN
3   2019-01-07  07:45:01.116860 32  152.53  152.54  21  NaN NaN OPEN    NaN
4   2019-01-07  07:45:01.116905 34  152.53  152.54  21  NaN NaN OPEN    NaN
5   2019-01-07  07:45:01.116982 34  152.53  152.54  31  NaN NaN OPEN    NaN
6   2019-01-07  07:45:01.147901 38  152.53  152.54  31  NaN NaN OPEN    NaN
7   2019-01-07  07:45:01.189971 38  152.53  152.54  31  ask 15.0    OPEN    152.54
8   2019-01-07  07:45:01.189971 38  152.53  152.54  16  NaN NaN OPEN    152.54
9   2019-01-07  07:45:01.190766 37  152.53  152.54  16  NaN NaN OPEN    152.54
10  2019-01-07  07:45:01.190856 37  152.53  152.54  15  NaN NaN OPEN    152.54
11  2019-01-07  07:45:01.190856 37  152.53  152.54  16  ask 1.0 OPEN    152.54
12  2019-01-07  07:45:01.193938 37  152.53  152.55  108 NaN NaN OPEN    152.54
13  2019-01-07  07:45:01.193938 37  152.53  152.54  15  ask 15.0    OPEN    152.54
14  2019-01-07  07:45:01.194326 2   152.54  152.55  108 NaN NaN OPEN    152.54
15  2019-01-07  07:45:01.194453 2   152.54  152.55  97  NaN NaN OPEN    152.54
16  2019-01-07  07:45:01.194479 6   152.54  152.55  97  NaN NaN OPEN    152.54
17  2019-01-07  07:45:01.194507 19  152.54  152.55  97  NaN NaN OPEN    152.54
18  2019-01-07  07:45:01.194532 19  152.54  152.55  77  NaN NaN OPEN    152.54
19  2019-01-07  07:45:01.194598 19  152.54  152.55  79  NaN NaN OPEN    152.54

【讨论】:

  • “vol.cumsum()”中的vol是什么?
  • 应该是“音量”
【解决方案2】:

这是一种可能的方法

追加VMAP 列,其中包含NaNs

df['VMAP'] = np.nan

计算VMAP(基于this等式provided by the OP)并根据ask或bid、as requierd by the OP赋值

for trade in ['ask','bid']:
    # Find indexes of `ask` or `buy`
    bid_idx = df[df.trade==trade].index

    # Slice DF based on `ask` or `buy`, using indexes
    df.loc[bid_idx, 'VMAP'] = (
        (df.loc[bid_idx, 'trade_size'] * df.loc[bid_idx, trade]).cumsum()
        /
        (df.loc[bid_idx, 'trade_size']).cumsum()
                )

print(df.iloc[:,1:])
               time  bid_size     bid     ask  ask_size trade  trade_size phase    VMAP
0   07:45:01.064515       495  152.52  152.54        19   NaN         NaN  OPEN     NaN
1   07:45:01.110072        31  152.53  152.54        19   NaN         NaN  OPEN     NaN
2   07:45:01.116596        32  152.53  152.54        19   NaN         NaN  OPEN     NaN
3   07:45:01.116860        32  152.53  152.54        21   NaN         NaN  OPEN     NaN
4   07:45:01.116905        34  152.53  152.54        21   NaN         NaN  OPEN     NaN
5   07:45:01.116982        34  152.53  152.54        31   NaN         NaN  OPEN     NaN
6   07:45:01.147901        38  152.53  152.54        31   NaN         NaN  OPEN     NaN
7   07:45:01.189971        38  152.53  152.54        31   ask        15.0  OPEN  152.54
8   07:45:01.189971        38  152.53  152.54        16   NaN         NaN  OPEN     NaN
9   07:45:01.190766        37  152.53  152.54        16   NaN         NaN  OPEN     NaN
10  07:45:01.190856        37  152.53  152.54        15   NaN         NaN  OPEN     NaN
11  07:45:01.190856        37  152.53  152.54        16   ask         1.0  OPEN  152.54
12  07:45:01.193938        37  152.53  152.55       108   NaN         NaN  OPEN     NaN
13  07:45:01.193938        37  152.53  152.54        15   ask        15.0  OPEN  152.54
14  07:45:01.194326         2  152.54  152.55       108   NaN         NaN  OPEN     NaN
15  07:45:01.194453         2  152.54  152.55        97   NaN         NaN  OPEN     NaN
16  07:45:01.194479         6  152.54  152.55        97   NaN         NaN  OPEN     NaN
17  07:45:01.194507        19  152.54  152.55        97   NaN         NaN  OPEN     NaN
18  07:45:01.194532        19  152.54  152.55        77   NaN         NaN  OPEN     NaN
19  07:45:01.194598        19  152.54  152.55        79   NaN         NaN  OPEN     NaN

编辑

作为@edinhocorrectly indicated,VMAP 与trade_price 列相同。

【讨论】:

    【解决方案3】:

    好的,就到这里

    df['trade_price'] = df.apply(lambda x: x['bid'] if x['trade']=='bid' else x['ask'], axis=1)
    df['vwap'] = (df['trade_price'] * df['trade_size']).cumsum() / df['trade_size'].fillna(0).cumsum()
    

    第一行:
    它将 trade_price 保存在一个新列中,以便以后检索它。
    如果你愿意,你可以删除这一行并做一个函数(也许它更容易阅读)。但我更喜欢看中间结果。
    问:为什么即使没有交易它也有价值?
    答:因为 lambda 的编写方式。 else 捕获 ask 价格。但这不会有什么不同,因为下一步。

    第二行:
    真正的计算发生在这里。
    第一部分计算直到那一刻的总交易量(正如您所说,使用累积总和让生活更轻松)。
    第二部分计算直到那一刻的总交易量(同样是累积总和)。
    如果你愿意,你可以打破这条线,做更多的中间列。
    问:为什么是fillna(0)?
    A:所以总音量不会得到NaNs,你不会得到除法错误 问:为什么vwap 列中有这么多NaNs?
    A:因为没有交易的线路。您可以填写0s,但最好保留“禁止交易”信息。

    Ps.:你可能会得到一个错误的结果,因为它只考虑同一个方向的数量和价格。但是,您可以尝试反转一些信号以按照您期望的方式固定交易量(例如:将 ask 价格更改为负数)。

    这个代码输出:

        trade_price vwap
    1   152.54  NaN
    2   152.54  NaN
    3   152.54  NaN
    4   152.54  NaN
    5   152.54  NaN
    6   152.54  NaN
    7   152.54  NaN
    8   152.54  152.54
    9   152.54  NaN
    10  152.54  NaN
    11  152.54  NaN
    12  152.54  152.54
    13  152.55  NaN
    14  152.54  152.54
    15  152.55  NaN
    16  152.55  NaN
    17  152.55  NaN
    18  152.55  NaN
    19  152.55  NaN
    20  152.55  NaN
    

    【讨论】:

      猜你喜欢
      • 2019-11-02
      • 2017-12-04
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      相关资源
      最近更新 更多