이 전략은 Bollinger Bands를 사용하여 밴드 내부와 외부의 변동을 비교하여 트렌드를 판단하고, 트렌드를 추적하기 위해 모멘텀 지표를 사용합니다. 트렌드 다음 전략에 속합니다. 밴드 내부의 변동성이 외부보다 작을 때 새로운 트렌드 방향 신호를 생성하고 포지션을 열고 있습니다. 스톱 로스는 ATR 곱셈을 사용하고, 수익을 취하는 것은 위험 보상 비율의 ATR 곱셈입니다.
이 전략은 다음과 같은 주요 부분으로 구성됩니다.
볼링거 밴드 설정: 길이 40의 큰 밴드, 길이 20의 작은 밴드, 밴드 너비는 2 표준 편차입니다.
대역 폭발 판단: 큰 대역 상부가 작은 대역 상부의 아래에 있고, 큰 대역 하부는 작은 대역 하단의 위에 있으면 변동성이 증가하고 새로운 트렌드 방향 신호를 생성합니다.
동력 지표: 240 시간 14 EMA는 트렌드 방향을 판단합니다.
ATR 스톱 로스 및 수익을 취합니다: 스톱 로스 거리를 위해 ATR 14 배, 수익을 취하는 것은 스톱 로스 거리의 1.5 배입니다.
이 전략은 먼저 밴드가 폭발하는지 판단하고, 그 다음 모멘텀 방향에 따라 긴 또는 짧은 것을 결정합니다. 진입 후, Stop Loss를 위해 ATR 배수를 사용하여 이윤 관리를 취하십시오.
이중 볼링거 대역을 사용하면 트렌드 폭발 지점을 결정하기 위해 시간 프레임에 걸쳐 변동성을 비교할 수 있습니다.
동력 지표를 이용하면 시장의 변화로 인해 좌절을 피할 수 있습니다.
ATR 정차는 시장 변동성에 따라 정차 거리를 조정합니다.
합리적인 위험 보상 비율, 너무 공격적이거나 보수적이지 않습니다.
명확한 트렌드가 없는 시장에 갇혀 있을 수 있습니다. 잘못된 신호를 줄이기 위해 모멘텀 매개 변수를 최적화할 수 있습니다.
ATR 정류는 너무 보수적일 수 있습니다. 후속 정류와 같은 다른 정류 방법을 고려하십시오.
고정된 ATR 곱수는 모든 제품에는 적합하지 않을 수 있습니다. 조정 가능한 것을 고려하십시오.
이중 볼링거 효과는 증명되지 않았습니다. KD와 같은 다른 채널을 테스트하십시오.
최적의 조합을 찾기 위해 서로 다른 모멘텀 매개 변수를 테스트합니다.
다른 정지 방법을 시도해 보세요. 후속 정지, 적응형 ATR 같은 것이죠.
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 ===/ //