Strategi Perdagangan Bollinger Percent Bands

Penulis:ChaoZhang, Tanggal: 2023-12-11 11:14:53
Tag:

img

Gambaran umum

Strategi ini didasarkan pada indikator Bollinger Bands, dikombinasikan dengan moving average dan indikator teknis ATR, untuk menerapkan sistem breakout jangka pendek. Strategi ini menghitung posisi persentase relatif harga dalam saluran Bollinger Bands untuk menilai situasi overbought dan oversold, dikombinasikan dengan breakout tertinggi dan terendah baru untuk menghasilkan sinyal perdagangan.

Logika Strategi

  1. Menghitung Bollinger Bands saluran dan persentase relatif posisi harga dalam saluran
  2. Menghitung rata-rata bergerak secara terpisah untuk harga buka, tutup, tinggi dan rendah
  3. Menghitung indikator ATR dan mengatur garis stop loss yang dikombinasikan dengan ATR
  4. Pertimbangkan apakah harga mendekati puncak baru atau terendah baru
  5. Gabungkan puncak dan terendah tahunan untuk menilai tren jangka waktu yang lebih besar
  6. Menghasilkan sinyal perdagangan berdasarkan perubahan persentase Bollinger Bands dan puncak/rendah baru

Strategi ini menggunakan saluran Bollinger Bands untuk menilai volatilitas pasar, dengan lebar saluran yang ditentukan oleh standar deviasi. Sinyal beli dihasilkan ketika harga menembus band bawah, dan sinyal jual ketika harga menembus band atas. Rata-rata bergerak dapat meratakan fluktuasi Bollinger dan mengurangi kegagalan palsu. Indikator ATR dikombinasikan dengan stop loss trailing untuk memperbaiki skala stop loss. Tinggi/rendah baru membantu menghindari mengejar puncak dan membatasi penurunan. Tinggi/rendah tahunan menyaring konsolidasi jangka waktu yang lebih besar.

Keuntungan

  1. Filter Breakout Bollinger Bands yang ketat membantu mengurangi sinyal palsu
  2. Rata-rata bergerak merata harga dan mengidentifikasi tren yang benar
  3. Indikator ATR secara dinamis melacak stop loss dan membatasi kerugian perdagangan tunggal
  4. Tingkat tinggi/rendah baru dan tingkat tinggi/rendah tahunan membuat sinyal lebih dapat diandalkan
  5. Kombinasi yang efektif dari beberapa indikator meningkatkan efisiensi

Risiko dan Solusi

  1. Parameter Bollinger Bands yang tidak benar dapat menyebabkan pelanggaran palsu yang berlebihan, kombinasi parameter yang berbeda harus diuji untuk hasil terbaik
  2. Referensi harga penutupan dapat menyebabkan penarikan melebihi rentang stop loss yang ditetapkan ATR, pertimbangkan untuk menggunakan harga tinggi/rendah yang lebih fluktuatif untuk perhitungan persentase
  3. Filter Bollinger yang ketat dapat melewatkan beberapa peluang tren jangka panjang, melonggarkan filter dan periode penahan secara tepat
  4. Indikator ATR melacak perubahan harga yang besar perlahan, pertimbangkan ukuran volatilitas frekuensi yang lebih tinggi seperti rentang sejati
  5. Penembusan puncak/rendah baru mudah terganggu oleh kebisingan jangka pendek, mengevaluasi signifikansi statistik dan keberlanjutan tren

Arahan Optimasi

  1. Uji kombinasi parameter yang berbeda untuk menentukan parameter Bollinger optimal dan panjang rata-rata bergerak
  2. Menggunakan kombinasi model yang menggabungkan parameter Bollinger yang berbeda atau rata-rata bergerak
  3. Uji ketahanan dalam jangka waktu dan produk yang berbeda, meningkatkan kemampuan beradaptasi
  4. Masukkan sinyal jangka waktu yang lebih tinggi seperti sinyal Bollinger harian atau faktor musiman
  5. Mengevaluasi peluang mengikuti tren untuk memperluas cakupan strategi dan profitabilitas

Kesimpulan

Strategi ini secara efektif menggabungkan band persentase Bollinger, moving average, indikator ATR, high/low baru dan high/low tahunan untuk membangun sistem perdagangan breakout jangka pendek yang relatif ketat dan efisien. Keuntungannya yang luar biasa terletak pada penggunaan berbagai alat untuk mengurangi kebisingan dan mengidentifikasi sinyal tren sejati. Tentu saja strategi ini juga menghadapi beberapa kesulitan penyesuaian parameter dan peluang yang hilang dalam kondisi yang ketat. Secara keseluruhan, ini mewakili gaya perdagangan yang unik dan strategi breakout Bollinger yang efisien yang menjamin penelitian lebih lanjut dan validasi pada data perdagangan nyata.


/*backtest
start: 2022-12-04 00:00:00
end: 2023-12-10 00:00:00
period: 1d
basePeriod: 1h
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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Bollinger %B Candles Strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

BBLength = input(100, minval=1, step=1)
StdDev = 10
useMovingAverage = input(true)
MAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
lookbackPeriod = input(22, minval=10, step=10)
colorByPreviousClose = input(true)

AtrMAType = input(title="Moving Average Type", defval="hma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(10)
AtrMult = input(4)
wicks = input(false)

considerYearlyHighLow = input(false)
considerNewLongTermHighLows = input(false)
shortHighLowPeriod = 100
longHighLowPeriod = 200
tradeDirection = input(title="Trade Direction", defval=strategy.direction.all, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])

backtestYears = input(10, minval=1, step=1)


//////////////////////////////////// Calculate new high low condition //////////////////////////////////////////////////
f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)=>
    newHigh = highest(shortHighLowPeriod) == highest(longHighLowPeriod) or not considerNewLongTermHighLows
    newLow = lowest(shortHighLowPeriod) == lowest(longHighLowPeriod) or not considerNewLongTermHighLows
    [newHigh,newLow]

//////////////////////////////////// Calculate Yearly High Low //////////////////////////////////////////////////
f_getYearlyHighLowCondition(considerYearlyHighLow)=>
    yhigh = security(syminfo.tickerid, '12M', high[1]) 
    ylow = security(syminfo.tickerid, '12M', low[1]) 
    yhighlast = yhigh[365]
    ylowlast = ylow[365]
    yhighllast = yhigh[2 * 365]
    ylowllast = ylow[2 * 365]
    
    yearlyTrendUp = na(yhigh)? true : na(yhighlast)? close > yhigh : na(yhighllast)? close > max(yhigh,yhighlast) : close > max(yhigh, min(yhighlast, yhighllast))
    yearlyHighCondition = (  (na(yhigh) or na(yhighlast) ? true : (yhigh > yhighlast) ) and ( na(yhigh) or na(yhighllast) ? true : (yhigh > yhighllast))) or yearlyTrendUp or not considerYearlyHighLow
    yearlyTrendDown = na(ylow)? true : na(ylowlast)? close < ylow : na(ylowllast)? close < min(ylow,ylowlast) : close < min(ylow, max(ylowlast, ylowllast))
    yearlyLowCondition = (  (na(ylow) or na(ylowlast) ? true : (ylow < ylowlast) ) and ( na(ylow) or na(ylowllast) ? true : (ylow < ylowllast))) or yearlyTrendDown or not considerYearlyHighLow
    
    label_x = time+(60*60*24*1000*1)
    [yearlyHighCondition,yearlyLowCondition]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

inDateRange = true
[yearlyHighCondition,yearlyLowCondition] = f_getYearlyHighLowCondition(considerYearlyHighLow)
[newHighS,newLowS] = f_calculateNewHighLows(shortHighLowPeriod, longHighLowPeriod, considerNewLongTermHighLows)
[middleclose, upperclose, lowerclose] = bb(close, BBLength, StdDev)
[middleopen, upperopen, loweropen] = bb(open, BBLength, StdDev)
[middlehigh, upperhigh, lowerhigh] = bb(high, BBLength, StdDev)
[middlelow, upperlow, lowerlow] = bb(low, BBLength, StdDev)

percentBClose = (close - lowerclose)*100/(upperclose-lowerclose)
percentBOpen = (open - loweropen)*100/(upperopen-loweropen)
percentBHigh = (high - lowerhigh)*100/(upperhigh-lowerhigh)
percentBLow = (low - lowerlow)*100/(upperlow-lowerlow)

percentBMAClose = f_getMovingAverage(percentBClose, MAType, lookbackPeriod)
percentBMAOpen = f_getMovingAverage(percentBOpen, MAType, lookbackPeriod)
percentBMAHigh = f_getMovingAverage(percentBHigh, MAType, lookbackPeriod)
percentBMALow = f_getMovingAverage(percentBLow, MAType, lookbackPeriod)

newOpen = useMovingAverage? percentBMAOpen : percentBOpen
newClose = useMovingAverage? percentBMAClose : percentBClose
newHigh = useMovingAverage? percentBMAHigh : percentBHigh
newLow = useMovingAverage? percentBMALow : percentBLow

truerange = max(newHigh, newClose[1]) - min(newLow, newClose[1])

averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
atr = averagetruerange * AtrMult

longStop = newClose - atr
longStopPrev = nz(longStop[1], longStop)
longStop := (wicks ? newLow[1] : newClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop

shortStop = newClose + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := (wicks ? newHigh[1] : newClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop

dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and (wicks ? newHigh : newClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? newLow : newClose) < longStopPrev ? -1 : dir

trailingStop = dir == 1? longStop : shortStop

candleColor = colorByPreviousClose ?
                 (newClose[1] < newClose ? color.green : newClose[1] > newClose ? color.red : color.silver) : 
                 (newOpen < newClose ? color.green : newOpen > newClose ? color.red : color.silver)
plotcandle(newOpen, newHigh, newLow, newClose, title='PercentBCandle', color = candleColor, wickcolor=candleColor)
plot(trailingStop, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= dir == 1 ? color.green : color.red)

buyCondition = dir==1 and yearlyHighCondition and newHighS
exitBuyCondition = dir == -1
sellCondition = dir == -1 and yearlyLowCondition and newLowS
exitSellCondition = dir == 1
strategy.risk.allow_entry_in(tradeDirection)

barcolor(buyCondition? color.lime : sellCondition ? color.orange : color.silver)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca_buy")
strategy.close("Buy", when=exitBuyCondition)

strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca_sell")
strategy.close("Sell", when=exitSellCondition)

Lebih banyak