ボリンジャー・バンド・モメンタム・バースト戦略

作者: リン・ハーンチャオチャン, 日付: 2023-10-31 15:54:41
タグ:

img

概要

この戦略は,ボリンジャーバンドを使用して,バンド内外の変動を比較してトレンドを判断し,トレンドをフォローするためにモメントインジケーターを使用する.これはトレンドフォロー戦略に属している.バンド内での変動が外よりも小さいときに新しいトレンド方向信号を生成し,ポジションを開設する.ストップロスはATR倍数を使用し,利益を取ることはリスク報酬比のATR倍数である.

原則

戦略は以下の主要な部分で構成されています.

  1. ボリンガー帯の設定: 長さ40の大きな帯,長さ20の小さな帯,幅は2つの標準偏差です.

  2. バンド爆発判断: 大きいバンド上部が小さなバンド上部の下部で,大きいバンド下部が小さなバンド下部の上部にある場合,それは波動性の増加を示し,新しいトレンド方向信号を生成します.

  3. 動向指標: 240 時間枠 14 EMAはトレンド方向を判断する.

  4. ATR ストップ・ロストと 利益: ATR はストップ・ロスト距離の 14 倍で,利益はストップ・ロスト距離の 1.5 倍です.

戦略は,最初にバンドが爆発するかどうかを判断し,その後,モメント方向に基づいて長か短かを決定します. 入力後,ストップ損失のためにATR倍数を使用し,利益管理を行います.

利点

  1. 双ボリンガー帯を使用することで,トレンドブレイクポイントを決定するために,時間枠間の変動を比較することができます.

  2. 動向指標を使うと 市場が変化するのを避けられます

  3. ATRストップは,市場の変動に基づいてストップ距離を調整します.

  4. 合理的なリスク・報酬比で 攻撃的でも保守的でもない

リスク

  1. 明確なトレンドのない市場に閉じ込められ 誤った信号を減らすためにモメントパラメータを最適化できます

  2. ATRの停止は保守的すぎるかもしれない.他の停止方法を考慮してください.

  3. 固定ATR倍数はすべての製品に合わないかもしれません.調整可能なものにしよう.

  4. ダブル・ボリンガー効果は証明されていない. KDのような他のチャンネルをテスト.

オプティマイゼーションの方向性

  1. 異なるモメントパラメータをテストして 最適な組み合わせを見つけます

  2. トレイリングストップやアダプティブATRなど

  3. ATR倍数を製品と市場状況に基づいて調整できるようにする.

  4. 安定性を高めるために 異なるチャネルインジケーターをテストします

  5. より良い利益管理のために複合管理を追加することを検討します.

  6. 入力信号をスイングや時間などでフィルタリングして 勝率を向上させる

結論

戦略の論理は明確で,トレンドバーストを決定するためにデュアルボリンガーを使用することは最大のハイライトです. しかし,ストップ,チャネル,リスクマネジメントなどで,パラメータを異なる市場条件に適応できるようにするために最適化が必要です. 全体的に,戦略には良い利点と可能性があり,さらなる研究に値します.


/*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 ===/ //

もっと