实时组合状态更新,尽在http://49.51.196.202:5006/portfolio.html
下跌了,前方路滑,小心妖魔鬼怪出没。
延续昨天的话题。
波动率有很多种估计量。我们只介绍几个。为此,必须先引入几个符号。
首先是四个对数价格
然后,是正规化之后的开高收低价格。
可以看出,其实所谓的正规化价格,都是对数收益率:t期的正规收盘价、最高价、最低价是t期的绝对收盘、最高、最低价相对于t期绝对开盘价的对数收益率;t期的正规开盘价是t期的绝对开盘价相对于t-1期的绝对收盘价的对数收益率。
根据这些“价格”,我们就可以估计波动率。
RV:已实现波动率
已实现波动率是最简单的一种。它计算的就是收益率的波动率。在对数收益率均值为0的情况下,它的计算公式是:
均值不为0也没事,pandas 直接就搞定了
- da['rtn'] = da['ln_close'] - da['ln_close'].shift(1)
复制代码- r_v = da['rtn'].std(ddof=1)
复制代码
这里不用close也无妨,尤其是在金融数据中,收盘价往往是有鬼的。而且更美妙的是,如果你有更高频的数据,比如tick数据,也完全可以用类似的方法来算波动率。
RV是我们最喜爱的波动率之一。因为它充分用到了日内交易的信息,是一种依赖于“价格路径”的波动率。那么,RV这么简单,又充分利用了信息,为什么还要研究其他的波动率呢?
因为要计算RV的数据不是那么轻易可得的。且不说tick数据,就算是分钟级的数据,也不是地上随便捡的。这就催生了后面的一系列波动率,学界称为range estimator,也就是依赖于价格范围的波动率估计量,它们所需要的信息就少的多。
PK估计量
PK估计量依赖于资产价格服从几何布朗运动的假设。这个假设在很多情况下是否成立是存疑的,所谓价格服从几何布朗运动就是:
等式左边是微分形式的收益率,右边第一项是漂移项,代表收益率的趋势,第二项是波动项,代表收益率除了存在趋势之外,还存在一个均值为0,标准差为σ的正态分布扰动。
这个假设是否成立,如果不成立影响大不大,如果影响大,是否有代替方法,这些话题都太过于深奥,我们不可能在日报里写完。但有一点我们是肯定的:PK估计量只用到了h(t)和l(t),那用到的信息肯定比RV少。效果肯定是要打折扣的了,但在可得数据受限的情况下也没有办法。
GK估计量
在PK估计量横空出世之后,又有学者意识到,你这个PK估计量没有用到收盘价呀。所以,基于这一点,Garman和Klass两位老师提出了GK估计量
据GK两位说,GK估计量比PK估计量有效7.4倍,这个有零有整的7.4倍是咋来的我也没有精力去考证了…GK估计量依旧依赖于几何布朗运动的假设。
GKYZ估计量
在GK估计量横空出世之后,两位中国学者对它又进行了改进,提出了GKYZ的估计量(把自己的名字首字母加到了GK后面)
加上后面的这一项是为了涵盖opening jump,也就是跳空高开或者低开。
RS估计量
Roger和Satchell两位老师提出了这样一个估计量
RS估计量没有考虑开盘跳空的情景,但是,RS估计量是波动率的无偏估计量。
除了需要使用的信息少,这些range estimator还有一个比较优良的性质:range estimator比RV更加接近正态分布。所以,在进行假设检验和预测的时候,会比RV更好一些。
前面说了,RV估计量是我们最喜爱的波动率估计量之一,另外一个我们也特别喜欢的估计量就是隐含波动率IV。使用期权价格推算得到的波动率估计量。在我们之前的文章【量化交易日记00122】拿什么拯救你 我的波指 中有提到。
附上计算这些波动率的代码
- from datetime import timedelta
复制代码- pd.set_option('expand_frame_repr', False)
复制代码- df = pd.read_csv(data_path)
复制代码- def __init__(self, data):
复制代码- data['candle_begin_time'] = pd.to_datetime(data['candle_begin_time'])
复制代码- data['price'] = data[['open', 'high', 'low', 'close']].mean(axis=1)
复制代码- data[['ln_open', 'ln_high', 'ln_low', 'ln_close', 'ln_price']] = data[['open', 'high', 'low', 'close', 'price'
复制代码- ]].apply(lambda x: np.log(x))
复制代码- data['date'] = data['candle_begin_time'].dt.date
复制代码- data = data[['candle_begin_time', 'ln_open', 'ln_high', 'ln_low', 'ln_close', 'date']].copy()
复制代码- data['open'] = data['ln_open'] - data['ln_close'].shift(1)
复制代码- data['high'] = data['ln_high'] - data['ln_open']
复制代码- data['low'] = data['ln_low'] - data['ln_open']
复制代码- data['close'] = data['ln_close'] - data['ln_open']
复制代码- da['rtn'] = da['ln_close'] - da['ln_close'].shift(1)
复制代码- da.dropna(inplace=True, axis=0)
复制代码- r_v = x['rtn'].std(ddof=1)
复制代码- da.groupby('date').apply(f1)
复制代码- rv_df = pd.DataFrame(result, index=['rv']).T
复制代码- pk = ((x['high'].max() - x['low'].min()) ** 2) / (4 * np.log(2))
复制代码- da.groupby('date').apply(f1)
复制代码- pk_df = pd.DataFrame(result, index=['pk']).T
复制代码- gk = 0.5 * ((x['high'].max() - x['low'].min()) ** 2) - (2 * np.log(2) - 1) * (x['close'].iloc[-1]) ** 2
复制代码- da.groupby('date').apply(f1)
复制代码- gk_df = pd.DataFrame(result, index=['gk']).T
复制代码- if date != da['date'].iloc[0]:
复制代码- last_ln_close = da.loc[da['date'] == (date - timedelta(days=1)), 'ln_close'].iloc[-1]
复制代码- gk = 0.5 * ((x['high'].max() - x['low'].min()) ** 2) - (2 * np.log(2) - 1) * (x['close'].iloc[-1]) ** 2
复制代码- gkyz = gk + (x['ln_open'].iloc[0] - last_ln_close) ** 2
复制代码- da.groupby('date').apply(f1)
复制代码- gkyz_df = pd.DataFrame(result, index=['gkyz']).T
复制代码- rs = x['high'].max() * (x['high'].max() - x['close'].iloc[-1]) + \
复制代码- x['low'].min() * (x['low'].min() - x['close'].iloc[-1])
复制代码- da.groupby('date').apply(f1)
复制代码- rs_df = pd.DataFrame(result, index=['rs']).T
复制代码- price_data = PriceData(df)
复制代码- res_df = price_data.rv_esti()
复制代码- res_df['pk'] = price_data.pk_esti()
复制代码- res_df['gk'] = price_data.gk_esti()
复制代码- res_df['gkyz'] = price_data.gkyz_esti()
复制代码- res_df['rs'] = price_data.rs_esti()
复制代码
代码比较丑陋。
说到底,我们为什么要计算这些波动率呢?研究的目的是研究的过程中最容易忘记的东西。
回归初心,由于CTA策略本身是做多波动率的策略,而且我们也能够观察到,历史上波动率高的情况下,CTA策略的收益会高很多。那么我们就倾向于在波动率大的时候加大力度。所以,在当前建仓时,如果能够知道未来的波动率,就可以指导仓位的轻重,从而规避回撤,增加收益。
接下来几天我们会专注波动率的话题,敬请期待。
参考文献
Akindynos-Nikolaos Balta, Robert Kosowski (2012): Improving Time-Series Momentum StrategiesThe Role of Volatility Estimators and Trading Signals
题图
Vincent van Gogh: Seascape at Saintes-Maries
|
|