Strategi ini memperdagangkan penembusan harga Bollinger Bands. Ia bertujuan untuk menangkap peluang trend dari penembusan saluran.
Logik Strategi:
Mengira Bollinger Band dengan purata bergerak n-periode sebagai garis tengah dan band turun naik di atas dan di bawah.
Masuk pendek apabila harga merosot di bawah band bawah. Masuk panjang apabila memecahkan band atas.
Tetapkan berhenti di luar jalur bertentangan untuk kawalan risiko.
Sesuaikan lebar jalur berdasarkan pengeluaran maksimum untuk pengoptimuman parameter.
Tambah penapis kelantangan untuk mengelakkan gangguan palsu.
Kelebihan:
Putus band secara berkesan mengenal pasti perubahan trend.
Pengoptimuman parameter Bollinger adalah mudah dan praktikal.
Penapis jumlah meningkatkan kualiti dengan mengelakkan palsu.
Risiko:
Band yang tertinggal mungkin terlepas masa masuk terbaik.
Pembalikan selepas pecah adalah biasa, memerlukan hentian yang munasabah.
Mencari perdagangan frekuensi rendah dalam pengoptimuman boleh kehilangan peluang.
Ringkasnya, ini adalah strategi penembusan saluran biasa yang memperdagangkan Bollinger break. Peraturan yang agak mudah memberi manfaat kepada pengoptimuman tetapi masalah penempatan lag dan berhenti tetap memberi kesan kepada keuntungan yang stabil dalam 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)