我们都知道著名的随机震荡指标,它是MACD和RSI之外的主要指标之一。众所周知,它波动很大,有时会在很短时间内从超买区域转移到超卖区域。
随机振荡指标一直令我着迷,因为它的简单性和对已知归一化功能的使用。我发现它在技术分析中占据重要的地位,因此在量化交易中也使用了它。但是,我相信我们应该始终对所学知识进行创新,因此,在本文中,我们将优化该指标,令其能够反映价格的波动性。
本文来自《数据黑客》,登录官网可精彩资讯和文章。
随机震荡指标
随机震荡指标通过在计算中纳入高点和低点,试图找到超卖和超买区域。计算公式如下:
我们将创建以下函数,根据OHLC(高开低收)数据计算随机指标:
def stochastics(Data, lookback, what, high, low, where): for i in range(len(Data)): try: Data[i, where] = (Data[i, what] - min(Data[i - lookback + 1:i + 1, low])) / (max(Data[i - lookback + 1:i + 1, high]) - min(Data[i - lookback + 1:i + 1, low])) except ValueError: pass Data[:, where] = Data[:, where] * 100return Data# The Data variable refers to the OHLC array # The lookback variable refers to the period (5, 14, 21, etc.) # The what variable refers to the closing price # The high variable refers to the high price # The low variable refers to the low price # The where variable refers to where to put the Oscillator
上图显示了GBPUSD的随机震荡指标,回溯期等于14。由于指标的归一化函数的性质会使其介于最小值和最大值之间,因此该指标将始终在0到100之间。通常在交易软件中找到的默认参数是14,且具有某种形式的平滑。通常,其超买水平为20,超卖水平为80。
超买水平是一个被认为市场极为看涨的领域,超卖水平是指市场被视为极度看跌并势必反弹的领域。因此,随机震荡指标是一种逆势指标,旨在发出极端运动的信号。当然我们应保持谨慎,不要根据单一指标的信号做出决策。
调整波动率
适当地使用波动率调整是一个很好的工具,它可以通过修改公式以结合最近的波动率来帮助我们解释即将来临的信号或分析。但是什么是波动性?
最基本的波动率指标是标准差。它是描述性统计的支柱之一,并且是某些技术指标中的重要元素。它也用在著名的布林带中。首先让我们定义什么是方差,然后再找到标准差。
方差是与均值的平方偏差(离散量度),我们采用平方偏差以强制观测点与均值的距离为非负值,最后取平方根以使量度具有与均值相同的单位。简答来说,我们在某种程度上将苹果与苹果进行了比较(均值与标准差)。方差通过以下公式计算:
按照我们的逻辑,标准偏差等于:
下图显示了EURUSD货币对日图价格的标准差,采用过去20天的历史价格计算:
为了能够理解“标准偏差”(蓝色曲线)的含义,我们可以采用约0.0015点的最新值。从中我们推断出,遵循正态分布定律,我们预期下一根K线位于最近20个周期的平均值±0.0015之内的概率为68%。这意味着,随着欧元兑美元最新的20个周期的移动平均值位于1.1930左右,我们预计下一个柱线将在1.1945至1.1915之间,概率为68%。
下图描述了标准正态分布。
上面的曲线显示了在多个标准偏差内的值的数量。例如,用红色阴影表示的区域表示远离零平均值的标准偏差的1.33倍。假设数据服从正态分布,那么:
大约68%的数据落在平均值的1个标准差之内。大约95%的数据在平均值的2个标准差之内。大约99%的数据在平均值的3个标准差之内。
按照这种逻辑,我们有99%的把握确定下一个价格将在1.1885和1.1975之间。通过将标准偏差乘以3并将其加到当前平均值中,我们找到了这两个值。现在让我们回到对指标的研究。
我们想使用归一化将标准差度量限制在0到100的固定值之间。在之前的文章中,我们已经多次看到这种技术。长话短说,我们将使用以下函数将标准偏差指标转换为0到100之间的值,回溯期为20。这意味着,在任何时间点,如果我们在最近20个周期,我们将100作为归一化值。
def normalizer(Data, lookback, what, where): for i in range(len(Data)): try: Data[i, where] = (Data[i, what] - min(Data[i - lookback + 1:i + 1, what])) / (max(Data[i - lookback + 1:i + 1, what]) - min(Data[i - lookback + 1:i + 1, what])) except ValueError: pass Data[:, where] = Data[:, where] * 100 return Data
上图的第一个面板是EURUSD日图价格,第二个面板是价格标准差,第三个面板是归一化标准偏差。
我们采用以下逻辑,在随机指标上使用波动性:
每当最近20个周期的波动性相对较高时,向下推随机指标回溯期,以更多地考虑最近的值。每当最近20个周期的波动率相对较低时,将随机指标回溯期向上偏移,以减少对最近值的解释。
我们可以定义一个计算波动率的函数,如下所示:
def volatility(Data, lookback, what, where): for i in range(len(Data)): try: Data[i, where] = (Data[i - lookback + 1:i + 1, what].std()) except IndexError: pass return Data
但是,我们如何根据波动率指选择具体的回溯期?如果波动率上升,我们是否应将回溯期更改为15?16?还是9?
我们可以创建更复杂的规则,引入斐波那契数列,方法如下:
当波动率的归一化值在10到20之间时,随机指标的回顾期为89。当波动率的归一化值在20到30之间时,随机指标的回顾期为55。当波动率的归一化值在30到40之间时,随机指标的回顾期为34。当波动率的归一化值在40到50之间时,随机指标的回顾期为21。当波动率的归一化值在50到60之间时,随机指标的回顾期为13。当波动率的归一化值在60到70之间时,随机指标的回顾期为8。当波动率的归一化值在70到80之间时,随机指标的回顾期为5。当波动率的归一化值在80到90之间时,随机指标的回顾期为3。当波动率的归一化值在90到100之间时,随机指标的回顾期为2。
上面第一幅图显示通用的随机指标,第二幅图显示经波动性调整后的随机指标。
请记住,斐波那契数列遵循以下模式:
第n个斐波那契数字等于前两个数字之和:
这解释了上述根据波动性选择回溯期的规则。
上图的第一面板是美元兑瑞郎的日图价格,第二面板是经波动率调整的随机震荡指标,第三面板是ATR。
def fib_stoch(Data, volatility_lookback, what, where): Data = volatility(Data, volatility_lookback, what, where) Data = normalizer(Data, volatility_lookback, where, where + 1)for i in range(len(Data)): Data[i, where + 1] = round(Data[i, where + 1], 0) for i in range(len(Data)): if Data[i, where + 1] >= 0 and Data[i, where + 1] <= 10 : Data[i, where + 1] = 144 if Data[i, where + 1] > 10 and Data[i, where + 1] <= 20 : Data[i, where + 1] = 89 if Data[i, where + 1] > 20 and Data[i, where + 1] <= 30 : Data[i, where + 1] = 55 if Data[i, where + 1] > 30 and Data[i, where + 1] <= 40 : Data[i, where + 1] = 34 if Data[i, where + 1] > 40 and Data[i, where + 1] <= 50 : Data[i, where + 1] = 21 if Data[i, where + 1] > 50 and Data[i, where + 1] <= 60 : Data[i, where + 1] = 13 if Data[i, where + 1] > 60 and Data[i, where + 1] <= 70 : Data[i, where + 1] = 8 if Data[i, where + 1] > 70 and Data[i, where + 1] <= 80 : Data[i, where + 1] = 5 if Data[i, where + 1] > 80 and Data[i, where + 1] <= 90 : Data[i, where + 1] = 3 if Data[i, where + 1] > 90 and Data[i, where + 1] <= 100 : Data[i, where + 1] = 2 Data = jump(Data, volatility_lookback) for i in range(len(Data)): try: lookback = int(Data[i, where + 1]) Data[i, where + 2] = (Data[i, what] - min(Data[i - lookback + 1:i + 1, 2])) / (max(Data[i - lookback + 1:i + 1, 1]) - min(Data[i - lookback + 1:i + 1, 2])) except ValueError: passreturn Data
现在,让我们基于这种改进的振荡器创建交易策略,并进行回溯检验。
回测策略
现在,我们要对新的震荡指标进行回测,看看它是否有助于提升市场择时能力。像往常一样,选择2000年至今的3小时图作为样本,止盈是1倍ATR,止损是2倍ATR。这样的风险回报设置可能不是最佳选择,但我宁愿在强平之前给策略更多的喘息时间。
当波动性调整随机指标下穿10,空头平仓,转为做多。当波动性调整随机指标上穿90,多头平仓,转为做空。
下图显示了策略在AUDCAD的回溯结果。
下图显示了多货币测试的结果。
结论
为什么写这篇文章?必须指出,上述方法并不能保证获利,如果您关注我的文章,您会注意到我将重点放在探索如何盈利上,而不是告诉你这个策略能盈利。在实际交易中,您应该在策略中引入自己的见解和研究,才能实现长期盈利的目标。
来源:Medium
作者:Sofien Kaabar
翻译校对:数据黑客
原文标题:Volatility-Adjusted Stochastics Oscillator — A Python Study
数据黑客:专注金融大数据,聚合全网最好的资讯和教程,提供开源数据接口。
我们聚合全网最优秀的资讯和教程:
金融大数据机器学习/深度学习量化交易数据工程编程语言,Python,R,Julia,Scala,SQL
我们提供开源数据接口:
下载国内和国外海量金融数据API接口,将数据整合到您的平台
如果觉得《Python量化策略:经波动率调整的随机震荡指标》对你有帮助,请点赞、收藏,并留下你的观点哦!