Bollinger Band Breakout Trading Strategi

Penulis:ChaoZhang, Tanggal: 2023-09-12 16:23:12
Tag:

Strategi ini memperdagangkan price breakout dari Bollinger Bands.

Logika Strategi:

  1. Menghitung Bollinger Bands dengan moving average periode n sebagai midline dan volatility band di atas dan di bawahnya.

  2. Masuk short saat harga turun di bawah band bawah. Masuk long saat naik di atas band atas.

  3. Set stop di luar band berlawanan untuk pengendalian risiko.

  4. Sesuaikan lebar band berdasarkan maksimum drawdown untuk optimasi parameter.

  5. Tambahkan filter volume untuk menghindari kebocoran palsu.

Keuntungan:

  1. Memutus band secara efektif mengidentifikasi perubahan tren.

  2. Optimasi parameter Bollinger sederhana dan praktis.

  3. Filter volume meningkatkan kualitas dengan menghindari falseout.

Risiko:

  1. Band yang tertinggal mungkin melewatkan waktu masuk terbaik.

  2. Kembali setelah pecah adalah hal yang umum, yang membutuhkan pemberhentian yang wajar.

  3. Mencari perdagangan frekuensi rendah dalam optimasi dapat kehilangan peluang.

Singkatnya, ini adalah strategi penembusan saluran yang khas untuk trading Bollinger break. Aturan yang relatif sederhana menguntungkan optimasi tetapi masalah penempatan lag dan stop tetap mempengaruhi keuntungan stabil jangka panjang.


/*backtest
start: 2023-08-12 00:00:00
end: 2023-09-11 00:00:00
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=2
// strategy("ChannelBreakOutStrategyV2.1", commission_type = "percent", commission_value = 0.1, calc_on_order_fills = true, overlay=true)

length = input(title="Length",  minval=1, maxval=1000, defval=40)
maxR = input(title = "R",  minval = 1.0, maxval = 10, defval = 3, step = 0.1)
adoptR = input(title = "Auto Adjust R",  defval = false)
stepR = input(title = "Step in R",  minval = 0.01, maxval = 0.1, step = 0.01, defval = 0.02)
baseYear = input(title = "Base Year",  minval = 2000, maxval = 2016, defval = 2000)
volumeTh = input(title = "Volume Threadhold",  minval = 100.0, maxval = 200, defval = 120, step = 5)
hasLong = input(title = "Include Long",  defval = true)
hasShort = input(title = "Include Short",  defval = true)
usePositionSizing = input(title = "Enable Position Sizing",  defval = true)

getTrailStop(val, current) => 
    s = val > 1.6 ? 0.8 : val >= 1.4 ? 0.85 : val >= 1.3 ? 0.9 : 0.93
    s * current


upBound = highest(high, length)
downBound = lowest(low, length)
hasVol = (volume / sma(volume, length) * 100 >= volumeTh) ? 1 : 0

hasPos = strategy.position_size != 0 ? 1 : 0

trailstop = atr(length) * 3
ptvalue = syminfo.pointvalue
equity = strategy.openprofit > 0 ? strategy.equity - strategy.openprofit : strategy.equity
curR = adoptR == false ? maxR : n == 0 ? maxR : hasPos == 1 ? curR[1] : (rising(equity,1) > 0? curR[1] + stepR : falling(equity, 1) > 0 ? curR[1] <= 2.0 ? 2.0 : curR[1] - stepR : curR[1])
contracts = usePositionSizing == false ? 20 : floor(equity / 100 * curR / (trailstop * ptvalue))

realbuystop = close - trailstop
realsellstop = close + trailstop

isPFst = (hasPos[1] == 0 and hasPos == 1) ? 1 : 0
isPOn = (hasPos[1] + hasPos == 2) ? 1 : 0
largestR = hasPos == 0 or isPFst == 1 ? -1 : nz(largestR[1]) < close ? close : largestR[1]
pctRise =  largestR / strategy.position_avg_price

rbs = strategy.position_size <= 0 ? realbuystop : isPFst ? strategy.position_avg_price - trailstop : pctRise >= 1.3 ? getTrailStop(pctRise, largestR) : (isPOn and realbuystop > rbs[1] and close > close[1]) ? realbuystop : rbs[1]
rss = strategy.position_size >= 0 ? realsellstop : isPFst ? strategy.position_avg_price + trailstop : (isPOn and realsellstop < rss[1] and close < close[1]) ? realsellstop : rss[1]

isStart = na(rbs) or na(rss) ? 0 : 1
buyARun = close - open > 0 ? 0 : open - close
sellARun = open - close > 0 ? 0 : close - open

if (strategy.position_size > 0 and buyARun >= trailstop / 3 * 2 and pctRise < 1.3)
    strategy.close("buy")
    strategy.cancel("exit")
if (strategy.position_size < 0 and sellARun >= trailstop / 3 * 2)
    strategy.close("sell")
    strategy.cancel("exit")

strategy.cancel("buy")
strategy.cancel("sell")
conLong = hasLong == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("buy", strategy.long, qty = contracts, stop=upBound + syminfo.mintick * 5, comment="BUY", when = conLong)
if (rbs > high)
    strategy.close("buy")
strategy.exit("exit", "buy", stop = rbs, when = hasPos == 1 and isStart == 1)

conShort = hasShort == true and hasPos == 0 and year > baseYear and (isStart + hasVol) == 2
strategy.order("sell", strategy.short, qty = contracts, stop=downBound - syminfo.mintick * 5, comment="SELL", when = conShort)
if (rss < low)
    strategy.close("sell")
strategy.exit("exit", "sell", stop = rss, when = hasPos == 1 and isStart == 1)

plot(series = rbs, color=blue)
plot(series = realbuystop, color=green)
plot(series = rss, color=red)
plot(series = realsellstop, color=yellow)

Lebih banyak