该策略利用波尔带通道内外比较来判断趋势,并结合动量指标追踪趋势,属于趋势追踪策略。策略判断通道内波动小于通道外时产生新的趋势方向信号,并打开仓位。仓位止损采用ATR乘数,止盈为ATR乘数风险回报比例。
该策略主要由以下几部分组成:
波尔带设置:包括大波尔带长度40周期,小波尔带长度20周期,通道宽度为标准差的2倍。
通道 explosioin 判断:如果大波尔带上轨低于小波尔带上轨,大波尔带下轨高于小波尔带下轨,则说明波动加大,产生新的趋势方向信号。
动量指标: 240周期的14日EMA,判断趋势方向。
ATR止损止盈:ATR的14倍为止损距离,止盈为止损距离的1.5倍。
策略首先判断是否通道爆发,如果通道爆发,再判断动量方向,决定做多还是做空。入场后,以ATR倍数进行止损止盈管理。
使用双波尔带结构,可以比较不同时间周期内的波动情况,判断趋势爆发点。
借助动量指标判断趋势方向,避免被震荡市场 whipsaw。
利用ATR进行止损止盈管理,可以根据市场波动调整止损距离。
风险回报比例合理,避免过度追求,也不会过于保守。
在没有明确趋势的震荡行情中,容易被套住。可以通过优化动量指标参数来减少误判。
ATR止损可能会过于保守,可以测试其他止损方式,如移动止损等。
固定的止损止盈倍数可能不适合所有品种,可以考虑使其可调整。
双波尔带判断趋势转折点效果存疑,可以测试其他通道指标如KD通道等。
测试不同的动量指标参数,找到最佳参数组合。
尝试不同的止损方式,如移动止损,自适应ATR等。
使止损止盈倍数可调整,根据不同品种和市场环境优化。
测试不同通道指标的效果,选取更稳定的通道指标。
考虑加入复利管理,让盈利更可控。
可以根据波段、时间等过滤入场时机,提高胜率。
本策略整体思路清晰,使用双波尔带判断趋势爆发点是其最大亮点。但仍需针对止损方式、通道指标、风险管理等方面进行优化测试,使策略参数更具适应性,在不同市场环境中都能稳定运行。总体来说,该策略具有较好的优势和发展潜力,值得进行深入研究。
/*backtest
start: 2023-09-30 00:00:00
end: 2023-10-30 00:00:00
period: 1h
basePeriod: 15m
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/
// © kasaism
//@version=4
// strategy(title="[EURUSD60] BB Expansion Strategy", shorttitle="[EURUSD60] BBEXP",overlay=true, max_bars_back=5000, max_labels_count=500)
// === INPUTS === //
////BB
largeBbRes = input(title="Large BB Resolution", type=input.resolution, defval="", group="BB")
largeBbLength = input(title="Large BB Length", type=input.integer, defval=40, minval=1, group="BB")
smallBbRes = input(title="Small BB Resolution ", type=input.resolution, defval="", group="BB")
smallBbLength = input(title="Small BB Length", type=input.integer, defval=20, minval=1, group="BB")
multi = input(title="BB StdDev", type=input.float, defval=2.0, maxval=10, minval=0.01, group="BB")
validLen = input(title="BB expand valid length", defval=14, group="BB")
// 3 each EMA settings. EMA directions are as each time frame directions.
resFirstTime = input(title="EMA Trend t/f", type=input.resolution, defval="240", group="SMT")
// resSecondTime = input(title="Second t/f", type=input.resolution, defval="30", group="SMT")
// resThirdTime = input(title="Third t/f", type=input.resolution, defval="", group="SMT")
emaLen = input(14, minval=1, title="Length", group="SMT")
smooth = input(3, minval=1, title="Smooth factor", group="SMT")
//Lisk Management
var riskManagementRule1 = "ATR"
var riskManagementRule2 = "Bracket"
riskManagementRule = input(riskManagementRule1, "Detect Risk Management Based On", options=[riskManagementRule1, riskManagementRule2, "No detection"], group="Trade")
atrMulti = input(3.0, title="ATR Multiple", type=input.float, minval = 1.0, group="ATR")
riskRewardRatio = input(1.5, title="Risk Reward Ratio for ATR", type=input.float, minval = 0.01, group="ATR")
stopLossPoint = input(100, title="Stop Loss Point for Braket(tick)", type=input.float, minval = 1.0, group="Bracket")
takeProfitPoint = input(200, title="Take Profit Point for Braket(tick)", type=input.float, minval = 1.0, group="Bracket")
// === /INPUTS/ === //
// === CONSTANT === //
//For barmerge.lookahead_off
index = barstate.isrealtime ? 1 : 0
//For Entry
NOENTRY=0
LONG=1
SHORT=2
//SMT color
int up=1
int dn=2
int up_HL=3
int dn_HL=4
//label color
color_bearish = color.red
color_bullish = color.blue
C_label_color_bearish = color.red
C_label_color_bullish = color.blue
// === /CONSTANT/ === //
// === FUNCTIONS === //
//BB trade direction
bbTradeDetection(lrgUpper, lrgLower, smlUpper, smlLower) =>
if not(na(lrgUpper) or na(lrgLower) or na(smlUpper) or na(smlLower))
if lrgUpper < smlUpper and lrgLower > smlLower
true
else
false
else
na
// === /FUNCTIONS/ === //
// === CALCURATES === //
////BB
//large BB
lrgBbBasis = security(syminfo.tickerid, largeBbRes, sma(close[index], largeBbLength))
lrgBbDev = multi * security(syminfo.tickerid, largeBbRes, stdev(close[index], largeBbLength))
lrgBbUpper = lrgBbBasis + lrgBbDev
lrgBbLower = lrgBbBasis - lrgBbDev
//small BB
smlBbBasis = security(syminfo.tickerid, smallBbRes, sma(close[index], smallBbLength))
smlBbDev = multi * security(syminfo.tickerid, smallBbRes, stdev(close[index], smallBbLength))
smlBbUpper = smlBbBasis + smlBbDev
smlBbLower = smlBbBasis - smlBbDev
bbTrade = bbTradeDetection(lrgBbUpper, lrgBbLower, smlBbUpper, smlBbLower)
//EMA Trend
base=security(syminfo.tickerid, resFirstTime, ema(close[index],emaLen))
sig=security(syminfo.tickerid, resFirstTime, ema(base[index],smooth))
emaTrend = not(na(base) or na(sig)) ? base < sig ? dn : up : na
////LISK MANAGEMENT
float stopLossLineForLong = na
float stopLossLineForShort = na
float takeProfitLineForLong = na
float takeProfitLineForShort = na
atr_ = atr(14) * atrMulti
if riskManagementRule == riskManagementRule1
stopLossLineForLong := strategy.position_size > 0 ? stopLossLineForLong[1] ? stopLossLineForLong[1] : round(close[index] - atr_,3) : na
stopLossLineForShort := strategy.position_size < 0 ? stopLossLineForShort[1] ? stopLossLineForShort[1] : round(close[index] + atr_,3) : na
takeProfitLineForLong := strategy.position_size > 0 ? takeProfitLineForLong[1] ? takeProfitLineForLong[1] : close[index] + atr_*riskRewardRatio : na
takeProfitLineForShort := strategy.position_size < 0 ? takeProfitLineForShort[1] ? takeProfitLineForShort[1] :close[index] - atr_*riskRewardRatio : na
if riskManagementRule == riskManagementRule2
stopLossLineForLong := strategy.position_size > 0 ? stopLossLineForLong[1] ? stopLossLineForLong[1] : close[index] - stopLossPoint * syminfo.mintick : na
stopLossLineForShort := strategy.position_size < 0 ? stopLossLineForShort[1] ? stopLossLineForShort[1] : close[index] + stopLossPoint * syminfo.mintick : na
takeProfitLineForLong := strategy.position_size > 0 ? takeProfitLineForLong[1] ? takeProfitLineForLong[1] : close[index] +takeProfitPoint * syminfo.mintick : na
takeProfitLineForShort := strategy.position_size < 0 ? takeProfitLineForShort[1] ? takeProfitLineForShort[1] :close[index] - takeProfitPoint * syminfo.mintick : na
// === /CALCURATES/ === //
// === CONDITIONS === //
//BB
bool isBbEntry = na
for i=0 to validLen
isBbEntry := bbTrade==true ? true : bbTrade[i]==true ? true : false
//plotshape(isBbEntry, style=shape.circle, location=location.bottom)
isBbLong = isBbEntry and open[index] < smlBbBasis[index] and close[index] > smlBbBasis[index]
isBbShort = isBbEntry and open[index] > smlBbBasis[index] and close[index] < smlBbBasis[index]
//SMT
isEmaLong = emaTrend == up
isEmaShort = emaTrend == dn
//ATR
isAtrLongStop = low[index] <= stopLossLineForLong
isAtrShortStop = high[index] >= stopLossLineForShort
isAtrLongLimit = high[index] >= takeProfitLineForLong
isAtrShortLimit = low[index] <= takeProfitLineForShort
// === /CONDITIONS/ === //
// === TRADE === //
//ENTRY
if (isBbLong and isEmaLong)
strategy.entry("LongEntry", strategy.long, comment="LongEntry")
if riskManagementRule == riskManagementRule2
strategy.exit("LongEntry", loss=stopLossPoint, profit=takeProfitPoint, comment="bracket")
if (isBbShort and isEmaShort)
strategy.entry("ShortEntry", strategy.short, comment="ShortEntry")
if riskManagementRule == riskManagementRule2
strategy.exit("ShortEntry", loss=stopLossPoint, profit=takeProfitPoint, comment="bracket")
//EXIT
if riskManagementRule == riskManagementRule1
if(isAtrLongStop)
strategy.close("LongEntry", when=isAtrLongStop, comment="ATR Stop")
if(isAtrShortStop)
strategy.close("ShortEntry", when=isAtrShortStop, comment="ATR Stop")
if(isAtrLongLimit)
strategy.close("LongEntry", when=isAtrLongLimit, comment="ATR Limit")
if(isAtrShortLimit)
strategy.close("ShortEntry", when=isAtrShortLimit, comment="ATR Limit")
// === /TRADE/ === //
// === PLOTS === //
plot(lrgBbBasis, title="Large BB Basis", linewidth=2, color=color.gray)
plot(lrgBbUpper, title="Large BB Upper", linewidth=2, color=color.gray)
plot(lrgBbLower, title="Large BB Lower", linewidth=2, color=color.gray)
plot(smlBbBasis, title="Small BB Basis", color=color.white)
plot(smlBbUpper, title="Small BB Upper", color=color.white)
plot(smlBbLower, title="Small BB Lower", color=color.white)
plot(base, title="EMA Line", color= emaTrend==dn ? color_bearish : emaTrend==up ? color_bullish : color.gray)
plot(stopLossLineForLong ? stopLossLineForLong : na, title="S/L Line For Long", color=color.yellow, style=plot.style_circles)
plot(stopLossLineForShort ? stopLossLineForShort : na, title="S/L Line For Short", color=color.yellow, style=plot.style_circles)
plot(takeProfitLineForLong ? takeProfitLineForLong : na, title="T/P Line For Long", color=color.purple, style=plot.style_circles)
plot(takeProfitLineForShort ? takeProfitLineForShort : na, title="T/P Line For Short", color=color.purple, style=plot.style_circles)
// /=== PLOTS ===/ //