本策略基于价格的历史波动区间来确定交易信号。它计算一定周期内的最高价与最低价的差值,并通过移动平均线形成波动区间。当价格突破该区间的上下轨时,产生交易信号。属于基于价格突破的趋势跟踪策略。
该策略的核心指标是价格的历史波动率。具体计算方法是:
计算过去N根Bar的最高价和最低价之差,记为HL
计算过去N根Bar的最高价和最低价的平均值avg(H, L)
波动率 = HL / avg(H, L)
其中N为”Volatility Length”参数。
得到波动率后,计算上下轨:
上轨 = 当前close + 当前close * 波动率
下轨 = 当前close - 当前close * 波动率
上下轨再通过WMA均线做平滑处理,参数为”Average Length”。
当价格突破上轨时,做多;当价格突破下轨时,做空。
平仓信号根据”Exit Type”参数给定:
Exit Type为Volatility MA时,价格回破WMA均线平仓;
Exit Type为Range Crossover时,价格回破上下轨平仓。
可以通过以下措施减少风险:
该策略可以从以下几个方面进行优化:
通过测试不同的Length参数,找到最佳参数组合。
例如在价格突破上轨时,如果MACD也同时金叉,才入场做多。
可以优化为带有弹性的追踪止损,而不是简单的区间突破止损。
在止损出场后,如果趋势继续,可以设置再入场条件,对趋势进行再次追踪。
可以根据市场波动率的高低,动态调整交易仓位。
该策略总体来说比较适合趋势性行情,通过波动率上的轨和下轨来判断趋势方向和强度,并配合WMA均线形成较为可靠的交易区间,从而产生突破买卖点。但也存在一些问题,如趋势判断滞后,止损方式可以改进等。需要我们针对实盘数据进行大量的回测和优化,调整参数设置和策略规则,降低误入误出 probability,使策略在不同市场中都能有较好的表现。同时,严格的资金管理也是该策略能否长期盈利的关键。
/*backtest
start: 2023-09-13 00:00:00
end: 2023-09-20 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © wbburgin
//@version=5
strategy("Volatility Range Breakout Strategy [wbburgin]", shorttitle = "VRB Strategy [wbburgin]", overlay=true,
pyramiding=20,max_bars_back=2000,initial_capital=10000)
wma(float priceType,int length,float weight) =>
norm = 0.0
sum = 0.0
for i = 0 to length - 1
norm := norm + weight
sum := sum + priceType[i] * weight
sum / norm
// This definition of volatility uses the high-low range divided by the average of that range.
volatility(source,length) =>
h = ta.highest(source,length)
l = ta.lowest(source,length)
vx = 2 * (h - l) / (h + l)
vx
vm1 = input.int(100,"Average Length")
volLen = input.int(100,"Volatility Length")
vsrc = input.source(close,"Volatility Source")
cross_type = input.source(close,"Exit Source")
exit_type = input.string("Volatility MA",options=["Volatility MA","Range Crossover"],title="Exit Type")
volatility = volatility(vsrc,volLen)
highband1 = close + (close * volatility)
lowband1 = close - (close * volatility)
hb1 = wma(highband1,vm1,volatility)
lb1 = wma(lowband1,vm1,volatility)
hlavg = math.avg(hb1,lb1)
upcross = ta.crossover(high,hb1) //Crossing over the high band of historical volatility signifies a bullish breakout
dncross = ta.crossunder(low,lb1) //Crossing under the low band of historical volatility signifies a bearish breakout
vlong = upcross
vshort = dncross
vlong_exit = switch
exit_type == "Volatility MA" => ta.crossunder(cross_type,hlavg)
exit_type == "Range Crossover" => ta.crossunder(cross_type,hb1)
vshort_exit = switch
exit_type == "Volatility MA" => ta.crossover(cross_type,hlavg)
exit_type == "Range Crossover" => ta.crossover(cross_type,lb1)
if vlong
strategy.entry("Long",strategy.long)
if vlong_exit
strategy.close("Long")
if vshort
strategy.entry("Short",strategy.short)
if vshort_exit
strategy.close("Short")
plot(hlavg,color=color.white,title="Weighted Volatility Moving Average")
t = plot(hb1,color=color.new(color.red,50),title="Volatility Reversal Band - Top")
b = plot(lb1,color=color.new(color.green,50),title="Volatility Reversal Band - Bottom")
alertcondition(vlong,"Volatility Long Entry Signal")
alertcondition(vlong_exit,"Volatility Long Exit Signal")
alertcondition(vshort,"Volatility Short Entry Signal")
alertcondition(vshort_exit,"Volatility Short Exit Signal")
fill(t,b,color=color.new(color.aqua,90))