【问题标题】:Calculating volatility manually vs built-in functions are not the same手动计算波动率与内置函数不一样
【发布时间】:2020-09-21 21:23:23
【问题描述】:

有人可以帮助我了解我错在哪里吗?我不知道为什么每列的波动率不同...

这是我的代码示例:

from math import sqrt
from numpy import around
from numpy.random import uniform
from pandas import DataFrame
from statistics import stdev

data = around(a=uniform(low=1.0, high=50.0, size=(500, 1)), decimals=3)
df = DataFrame(data=data, columns=['close'], dtype='float64')
df.loc[:, 'delta'] = df.loc[:, 'close'].pct_change().fillna(0).round(3)

volatility = []

for index in range(df.shape[0]):
    if index < 90:
        volatility.append(0)
    else:
        start = index - 90
        stop = index + 1
        volatility.append(stdev(df.loc[start:stop, 'delta']) * sqrt(252))

df.loc[:, 'volatility1'] = volatility
df.loc[:, 'volatility2'] = df.loc[:, 'delta'].rolling(window=90).std(ddof=0) * sqrt(252)

print(df)

      close   delta  volatility1  volatility2
0    10.099   0.000     0.000000          NaN
1    26.331   1.607     0.000000          NaN
2    32.361   0.229     0.000000          NaN
3     2.068  -0.936     0.000000          NaN
4    36.241  16.525     0.000000          NaN
..      ...     ...          ...          ...
495  48.015  -0.029    46.078037    46.132943
496   6.988  -0.854    46.036210    46.178820
497  23.331   2.339    46.003184    45.837245
498  25.551   0.095    45.608260    45.792188
499  46.248   0.810    45.793012    45.769787

[500 rows x 4 columns]

非常感谢!

【问题讨论】:

    标签: python pandas volatility


    【解决方案1】:

    需要进行三个小改动。添加了 cmets 内联。 89 是必需的,因为端点包含(与许多其他 python 的东西不同)。 ddof=1 是必需的,因为 stdev 默认使用它。 This article 谈论 numpy std 而不是 stdev 但 ddof 所做的理论仍然相同。

    另外,将来,尝试将大小更改为 95 之类的值。调试时不需要其他 405 行,很高兴看到从 0/NaN 转换为实际波动率,看到你需要 89 而不是 90 .

    0 与 NaN 的差异仍然存在。这是您附加 0 和滚动的默认行为的结果。我不确定这是不是故意的,所以我离开了。

    from math import sqrt
    from numpy import around
    from numpy.random import uniform
    from pandas import DataFrame
    from statistics import stdev
    
    data = around(a=uniform(low=1.0, high=50.0, size=(500, 1)), decimals=3)
    df = DataFrame(data=data, columns=['close'], dtype='float64')
    df['delta'] = df['close'].pct_change().fillna(0).round(3)
    
    volatility = []
    
    for index in range(df.shape[0]):
        if index < 89: #change to 89
            volatility.append(0)
        else:
            start = index - 89 #change to 89
            stop = index
            volatility.append(stdev(df.loc[start:stop, 'delta']) * sqrt(252))
    
    df['volatility1'] = volatility
    df['volatility2'] = df.loc[:, 'delta'].rolling(window=90).std(ddof=1) * sqrt(252) #change to ddof=1
    
    print(df)
    

    【讨论】:

    • 谢谢!你能解释一下为什么我们从index - 89开始吗?我们应该跳过计算中的第一行 delta 吗?为什么volatility289 行中有值?应该是NaN 不?
    • Python 为 0 索引。所以第 90 个元素在索引 89 处。让我们使用 3 的窗口来演示。如果您位于索引 2,则您的 3 个元素是 0,1,&2。如果您的窗口是 90,那么在索引 89 处,您的 90 个元素是 0,1,...,88,&89。您会注意到问题中的 500 行从 0 到 499。您不会在计算中跳过 delta 的第一行。现在有意义吗?
    猜你喜欢
    • 1970-01-01
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 1970-01-01
    • 2021-11-16
    • 2021-11-09
    相关资源
    最近更新 更多