TB中的波动率代码如下:
Params
Series<Numeric> initdata; //价格序列
Numeric daylength(30); //标准差周期
Vars
Numeric yearfactor(245); //每年多少个交易日
Numeric mylength;
Series<Numeric> lnpricerate; //对数价格收益率序列
Numeric bsv; //历史波动率
Numeric i;
Numeric dayfactor(375); //每天多少根BAR
Numeric vt0(10);
Begin
if(BarStatus==0) Return vt0;
lnpricerate=ln(initdata/initdata[1]);
dayfactor=DayBarsNumI(0,1);
if(dayfactor==InvalidNumeric) Return vt0;
mylength=dayfactor*daylength;
//求年化波动率
bsv=100*Sqrt(yearfactor*dayfactor)*0.01*StandardDev(100*lnpricerate,mylength,2);
if(bsv==0 or bsv==InvalidNumeric) bsv=vt0;
Return bsv;
End
具体实现流程逻辑如下:
1. 定义参数和变量
参数:
- initdata: 价格序列
- daylength: 标准差周期
变量:
- yearfactor: 每年的交易日数,用于计算年化波动率
- mylength: 实际使用的周期数,等于标准差周期乘以每日BAR数
- lnpricerate: 对数价格收益率序列
- bsv: 历史波动率
- i: 计数器
- dayfactor: 每日BAR数
- vt0: 初值
2. 计算对数价格收益率
将价格序列转换为对数价格,然后计算对数价格的收益率序列lnpricerate
3. 计算历史波动率
使用StandardDev计算lnpricerate序列的历史波动率,波动率的周期数为mylength。根据年化计算公式,将波动率乘以一年的交易日数yearfactor和每个交易日的BAR数dayfactor,再除以100和100%,得到对数价格收益率的年化波动率。
4. 处理异常值
若计算所得历史波动率bsv为0或Invalid
关键代码:
其中的关键代码就是bsv=100*Sqrt(yearfactor*dayfactor)*0.01*StandardDev(100*lnpricerate,mylength,2);
这一行代码的详细解释如下:
1. 100: 表示将对数价格收益率lnpricerate乘以100,将其转化为百分比形式,使得波动率bsv也是以百分比的形式给出。
2. Sqrt(yearfactor * dayfactor): 在计算波动率之前,需要先计算波动率的周期数。为了将波动率转化为年化波动率,将yearfactor表示每年的交易日数,dayfactor表示每个交易日的BAR数。那么对于一个标准差周期,实际使用的周期数就是yearfactor * dayfactor。
3. 0.01: 将结果乘以0.01,得到波动率的百分比形式。
4. StandardDev(100 * lnpricerate, mylength, 2): 计算对数价格收益率序列lnpricerate的历史波动率,时长为mylength个周期,这里选择的是样本数据的修正标准差(也称为Bessel标准差),即将样本标准差乘以sqrt((N-1)/N),其中N为样本数量,N-1即为样本自由度(用于估计总体方差时自由变量的数量)。100 * lnpricerate是将对数价格收益率转换为百分比形式,将其单位与价格序列保持一致。
5. 综上所述,代码表示:将对数价格收益率转化为百分比形式,按每日BAR数计算标准差周期的周期数,使用修正标准差计算历史波动率,再将结果乘以100,得到年化波动率的百分比形式。
思考:对于波动率,有以下几点个人思考:
第一:日周期和其他周期的差异在哪里?根据公式代码可以知道,无论什么周期(30m,1h或者1d),都已经折算成了(n日的)年化波动率。因此在不同周期中也是可以进行对比的
日周期波动率与1H周期波动率的异同:
变化一致:趋势上基本保持一致,高低点出现的位置时间也都保持一致。
数值不同:但是波动率的值是有所不同的,比如波动率最高点都是22年4月1,日周期为33.16,1H周期为30.95。22年底那波的波动率最高点,日周期为26.86,1H周期为22.47
小周期更连续平滑:由于小周期的样本更多,单个样本对整体波动率的影响更小,同时,在小周期上,每根BAR所统计的N日波动率,是用N来确定bar数量,因此不是真实的前N日,只是数量上等于n日的数量,因此统计下来也更加的连续和平滑。
应用层面:抛开数值的不同,由于小周期更加平滑、快速和精准,因此在应用中,个人觉得在小周期使用这个波动率公式更好。
第二,ATR与Volatility:ATR与Volatility同样作为衡量波动率的指标,两者的差异在哪里?
ATR使用了更多的信息:波动率指标只用到了收盘价这1个信息,而ATR指标用到了更多最高和最低价和前一个收盘价3个信息(虽然大部分时间里只用2个)。
数值上不可比:ATR与Volatility的单位不同,无法直接比较。只能自己与自己比。
历史回测走势:无论是日周期,还是小时周期,参数上无论20日还是5日,只要是相同的统计参数(如图中的20日-80根1hbar),其波动率走势基本是一样的。不过细节上的数据还是存在细微不同的。单从观察来看,ATR的变化更敏锐,快速,且更加平滑,有些波动率高低点比Volatility要提前。
应用上:鉴于ATR用到了更多的信息,且变化更加的敏锐和平滑,因此逻辑上来说个人更倾向于使用ATR作为个人使用的波动率指标。
第三,波动率参数:波动率设定是需要有一个参数的,比如TB中的Volatility公式,参数设置默认是30日,ATR的默认参数是14,但是这个参数在公式的具体应用中应该如何设定?
基于策略需要:具体问题具体分析,根据策略需要确定参数。一般来说小周期策略,可以使用较小的参数,而相反,大周期策略就应该使用大周期波动率参数。
如同MA和其他技术指标:作为技术指标之一,逻辑上来说,波动率的指标和其他技术指标一样,基于个人对于市场的理解,服务于策略的设计。
第四,波动率的应用:从应用角度来看,波动率指标有哪些指导意义?
仓位设定:一般逻辑是,高波动低仓位,低波动高仓位。在很多现有的公式中,仓位的设定都是需要使用历史波动率来确定的。
止损设定:一般逻辑是,大波动打止损,小波动小止损。比如移动止损,很多策略中也会使用到ATR指标。